question de strncpy (langage C)

J’ai des difficultés avec strncpy. J’essaie de scinder une chaîne de 8 caractères en deux (les 6 premiers caractères d’une sous-chaîne, puis les 2 derniers caractères d’une autre) Pour illustrer cette difficulté particulière, j’ai simplifié mon code comme suit:

include stdio.h include stdlib.h include ssortingng.h define MAXSIZE 100 struct word { char ssortingng[8]; char sub1[2]; char sub2[6]; }; typedef struct word Word; int main(void) { Word* p; p=(Word*)malloc(MAXSIZE*sizeof(Word)); if (p==NULL) { fprintf(stderr,"not enough memory"); return 0; } printf("Enter an 8-character ssortingng: \n"); scanf("%s",p->ssortingng); strncpy(p->sub2,p->ssortingng,6); strncpy(p->sub1,p->ssortingng,2); printf("ssortingng=%s\n",p->ssortingng); printf("sub1=%s\n",p->sub1); printf("sub2=%s\n",p->sub2); free(p); return 0; } 

L’utilisateur est invité à entrer. Supposons qu’ils entrent “12345678”. Alors le résultat du programme est:

 ssortingng=1234567812123456 sub1=12123456 sub2=123456 

La sortie que j’attends serait la suivante:

 ssortingng=12345678 sub1=12 sub2=123456 

Je ne comprends pas comment strncpy semble append des chiffres à une chaîne … Évidemment, je ne comprends pas assez bien strncpy, mais quelqu’un peut-il m’expliquer ce qui se passe?

Les chaînes C doivent être terminées par un caractère nul (0).

strncpy ne met pas de terminateur null sur la chaîne pour vous. Si vous voulez une chaîne de 2 caractères, vous devez allouer de la place pour trois caractères et définir la dernière sur null.

Essaye ça:

 struct word { char ssortingng[9]; char sub1[3]; char sub2[7]; }; // ... strncpy(p->sub2,p->ssortingng,6); p->sub2[6] = 0; strncpy(p->sub1,p->ssortingng,2); p->sub1[2] = 0; // ... 

Notez que si l’utilisateur entre plus de caractères que prévu, vous aurez des problèmes.

Vous pouvez trouver cette partie de la documentation de strncpy utile:

La fonction strncpy () est similaire, sauf qu’au plus n octets de src sont copiés. Avertissement: S’il n’y a pas d’octet null parmi les n premiers octets de src, la chaîne placée dans dest ne sera pas terminée par la valeur null.

Vous imprimez des chaînes qui ne sont pas terminées par zéro. Pour résoudre ce problème, déclarez sub1 et sub2 avec un caractère supplémentaire pour le terminateur:

 char sub1[3]; char sub2[7]; 

Et puis null terminer après avoir copié:

 strncpy(p->sub2,p->ssortingng,6); p->sub2[6] = '\0'; strncpy(p->sub1,p->ssortingng,2); p->sub1[2] = '\0'; 

La fonction strncpy () copie au maximum n caractères de s2 en s1. Si s2 est inférieur à n caractères, le rest de s1 est rempli de caractères “\ 0”. Sinon, s1 n’est pas terminé.

Donc, étant donné que votre chaîne est plus longue, les chaînes ne sont pas terminées à zéro. Lorsque vous les imprimez, prinf imprime les caractères que vous avez copiés, mais continue ensuite d’imprimer ce qui existe jusqu’à ce qu’il atteigne un caractère NUL.

Bien que scanf ne termine pas sa chaîne par NUL, vous n’avez pas alloué suffisamment d’espace. Ssortingng dans votre structure doit comporter 9 caractères – 8 pour les caractères (12345678) et un de plus pour le NUL. En ce moment, le NUL est dans le premier caractère de str1 – que vous écrasez ensuite avec strncpy