2017-09-28 5 views
-1

J'essayais juste un code aléatoire et ai trouvé un problème étrange. Voici mon codeL'appel suivant à la fonction de fgets dans c n'obtenant pas les résultats désirés

#include<stdio.h> 
int main(void) { 
char name[6],name2[6]; 
fgets(name,100,stdin); 
fgets(name2,100,stdin); 
printf("%s\n",name); 
printf("%s\n",name2); 
return 0; 
} 

Ce code est l'impression que ce que j'ai fourni en entrée dans nom2 tableau et il n'est pas l'impression du tableau de noms


Par exemple: sur les entrées

abcdef 
zyxwvu 

le code imprime seulement la chaîne ci-dessous

zyxwvu 

Un autre problème: si je donne une deuxième chaîne qui est plus grande que la taille. Par exemple:

abcdef 
zyxwvug  // name2 is defined to be 6 characters and I have given 7 here 

alors son impression:

g 
zyxwvug 

S'il vous plaît aidez-moi à comprendre ce qui se passe. J'utilise le compilateur Gcc sur le code: blocs IDE :)

+3

'char name [6], nom2 [6]; fgets (nom, 100, stdin); fgets (nom2,100, stdin) '->' nom de caractère [8], nom2 [8]; fgets (nom, 8, stdin); fgets (nom2,8, stdin) ' – BLUEPIXY

+0

Compilez avec toutes les informations d'avertissement et de débogage (' gcc -Wall -Wextra -g'). Améliorez votre code pour ne recevoir aucun avertissement. Utilisez le débogueur 'gdb' et [valgrind] (http://valgrind.org/). –

+3

Vous écrivez hors des limites des tableaux, provoquant un comportement indéfini. – Barmar

Répondre

0

Comme indiqué dans les commentaires, votre problème vient de l'utilisation de fgets.

fgets

Si nous lisons fgets manual:

fgets() lit au plus un de moins que les caractères de taille de flux et les stocke dans la mémoire tampon pointée par s. La lecture s'arrête après un EOF ou une nouvelle ligne. Si un retour à la ligne est lu, il est stocké dans le tampon. Un octet nul final (\0) est stocké après le dernier caractère du tampon.

Qu'est-ce que cela signifie?

Lorsque vous écrivez fgets(name, 100, stdin);, qui suppose:

    données
  • seront lues à partir stdin,
  • données seront stockées dans name,
  • au plus 99 caractères seront lus à partir stdin et stockés dans name ,
  • un caractère \0 sera ajouté à name.

cordes

Qu'est-ce que cela veut dire, nous essayons de lire 100 caractères, nous obtenons seulement 99? Ceci est dû à la chaîne stockée dans C: une chaîne est une suite de caractères, terminée par \0.En utilisant ce fait, les fonctions et les personnes savent quelle est la longueur d'une chaîne.

Pensez aux fonctions strlen ou strcpy.

Par exemple:

/* this string is valid: we explictily terminate it */ 
char valid_string[5] = {'g', 'o', 'o', 'd', '\n'}; 

/* this string is not: we do not know what is after the 'd' in memory 
    the next '\0' can be far away... */ 
char valid_string[3] = {'b', 'a', 'd'}; 

votre problème

Donc, votre problème est le suivant:

  • vous réserve deux choix de 6 caractères comptant le \0, vous ne serez capable de stocker 5 char dans ces chaînes
  • vous t ell fgets que c'est correct d'utiliser 100 caractères dans votre chaîne.

Lors de l'exécution du programme, si vous donnez:

  • 4 char ou moins chaîne (ex: "ABCD"): qui fonctionne, fgets écriront abcd\n\0 dans name
  • 5 char ou more string: vous aurez un comportement indéfini: le caractère supplémentaire sera stocké après la chaîne, comme vous l'avez remarqué: lorsque vous donnez zyxwvug pour la deuxième chaîne, la première se remet ...

Comment fixer

#include<stdio.h> 

#define STRING_SIZE 6 
#define STRING_SIZE_INCLUDING_FINAL_0 (STRING_SIZE+1) 

int main(void) { 
    /* defines array to store what we want (6 char string here) */ 
    char name[STRING_SIZE_INCLUDING_FINAL_0]; 
    char name2[STRING_SIZE_INCLUDING_FINAL_0]; 

    /* use fgets we right way: 
     fgets is told what is the size of my arrays. 
     Warning, this sizeof operation won't work with pointers... */ 
    fgets(name, sizeof name, stdin); 
    fgets(name2, sizeof name2, stdin); 

    /* display the result */ 
    printf("'%s'\n",name); 
    printf("'%s'\n",name2); 
    return 0; 
}