2010-06-24 4 views
7

Je suis perplexe par la différence suivante dans le comportement:fscanf/fscanf_s différence de comportement

// suppose myfile.txt contains a single line with the single character 's' 
    errno_t res; 
    FILE* fp; 
    char cmd[81]; 

    res = fopen_s(&fp, "D:\\myfile.txt", "rb"); 
    fscanf(fp,"%80s",cmd); // cmd now contains 's/0' 
    fclose(fp); 

    res = fopen_s(&fp, "D:\\myfile.txt", "rb"); 
    fscanf_s(fp,"%80s",cmd); // cmd now contains '/0' ! 
    fclose(fp); 

Les résultats ne dépendent pas de l'ordre de l'appel (c.-à-appeler fscanf_s d'abord, vous obtiendrez le vide chaîne en premier). Compilé sur VC++ - VS2005. Quelqu'un peut-il se reproduire? Quelqu'un peut-il expliquer?

Merci!

Répondre

8

De la documentation sur fscanf_s(), http://msdn.microsoft.com/en-us/library/6ybhk9kc.aspx:

La principale différence entre les fonctions sécurisées (avec le suffixe _S) et les anciennes fonctions est que les fonctions sécurisées exiger que la taille de chaque champ c, C, s, S et [type soit passée en argument immédiatement après la variable. Pour plus d'informations, voir scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l et scanf Width Specification.

Et http://msdn.microsoft.com/en-us/library/w40768et.aspx:

Contrairement scanf et wscanf, scanf_s et wscanf_s nécessitent la taille de tampon à spécifier pour tous les paramètres d'entrée de type c, C, S, S, ou [. La taille de la mémoire tampon est transmise en tant que paramètre supplémentaire immédiatement après le pointeur vers la mémoire tampon ou la variable. Par exemple, si vous lisez une chaîne, la taille de la mémoire tampon de cette chaîne est transmise comme suit:

char s [10];

scanf ("% 9s", s, 10);

Donc, vous devriez l'appeler comme ceci:

fscanf_s(fp,"%80s",cmd, sizeof(cmd)); 
6

fscanf_s (et toute la famille scanf_s) exige que vous passez la taille après le tampon lui-même de toute %c, %C, %s, %S ou %[; vous omettre cet argument:

fscanf_s(fp, "%80s", cmd, 81); 
+3

Cela semble être exactement la mauvaise utilisation. '81' est censé être la taille du tampon' cmd'. Mais est-ce? C'est un bon moyen d'écrire du code qui plante, même en utilisant une fonction "sécurisée". Il devrait y avoir 'sizeof (cmd)' en cas de lecture dans un tableau statique de caractères, une variable qui stocke la longueur à laquelle le tampon est alloué, ou une fonction d'appel à la taille/capacité d'un tampon donné. Bien que votre exemple soit techniquement correct, il peut être trompeur pour beaucoup de gens. –

2

Votre question est étiqueté C++ et vous compilez en VC++, mais en utilisant fscanf? Obtenez un std :: ifstream.

std::string buffer; 
std::ifstream fp("my filepath"); 
fp >> buffer; 
Questions connexes