2016-12-13 2 views
0

Lorsque le tableau de caractères substring[#] est défini sur [64], le fichier génère un caractère supplémentaire. Le caractère supplémentaire varie à chaque compilation. Parfois es?, parfois esx entre autres.C Pourquoi une variable non apparentée/non déclarée influence-t-elle la sortie d'une autre variable?

Si je change le [64] en tout autre nombre (au moins ceux que j'ai essayés: 65, 256,1 ..) il sort correctement comme es.

Encore plus étrange, si je laisse le tableau de caractères utilisé/non déclaré char newString[64] dans ce fichier, il affiche la sous-chaîne correcte es même avec le 64.

  1. Comment la taille apparemment arbitraire de 64 affecte l'out ?
  2. Comment un tableau de caractères complètement indépendant (newString) influence-t-il la sortie d'un autre tableau de caractères?

.

int main() { 
    char string[64];  
    char newString[64]; 
    char substring[64]; 

    fgets(string,64,stdin); 
    strncpy(substring, string+1, 1); 
    printf("%s\n", substring); 

    return 0; 
} 
+1

Attention à l'utilisation correcte de 'strncpy'; il n'ajoute pas de zéro final. Il semble que vous pensiez qu'il va "extraire" une sous-chaîne de l'autre. – usr2564301

+3

Votre programme a un comportement indéterminé. Donc la prémisse entière de votre question est fausse - il ne sert à rien de demander une explication pour le comportement de UB. Votre question devrait être - où est le bug dans mon code. La réponse à cela est probablement ici: 'strncpy (substring, string + 1, 1)'. 'string + 1' saute toute la chaîne de caractères et pointe sur l'octet qui suit. Et vous ne copiez que 1 octet, puis essayez de l'imprimer en tant que chaîne. – kaylum

+0

Quelle est votre contribution? – chux

Répondre

3

Le problème est, strncpy() ne copiera pas la terminaison null parce que vous avez demandé de ne pas.

à l'aide strncpy() est sûr et dangereux en même temps, car il ne copie pas toujours la terminaison null, également l'utiliser pour un seul octet est inutile, au lieu faire

substring[0] = string[1]; 
substring[1] = '\0'; 

et il travaille.

Vous devriez lire la page de manuel strncpy(3) pour comprendre ce que je veux dire correctement, si vous lisez attentivement le manuel chaque fois que vous deviendrez un meilleur programmeur dans un temps plus court.

+1

Je suggère de tester si la chaîne a une longueur d'au moins 2 afin de ne pas prendre en charge les caractères après la fin de la chaîne (ce qui n'est probablement pas prévu). par exemple. if (strlen (string)> = 2) sous-chaîne [0] = chaîne [1] sinon sous-chaîne [0] = '\ 0'; –

+0

@StephanLechner Ce serait une très bonne pratique de vérifier, je ne vais pas modifier la réponse puisque le commentaire est suffisant. –