web-dev-qa-db-fra.com

Pourquoi dois-je d'abord strcpy () avant strcat ()?

Pourquoi ce code génère-t-il des problèmes d'exécution:

char stuff[100];
strcat(stuff,"hi ");
strcat(stuff,"there");

mais ce n'est pas?

char stuff[100];
strcpy(stuff,"hi ");
strcat(stuff,"there");
23
Or Cyngiser

strcat cherchera le terminateur null, interprétera cela comme la fin de la chaîne et y ajoutera le nouveau texte, écrasant le terminateur null dans le processus et écrivant un nouveau terminateur nul à la fin de la concaténation.

char stuff[100];  // 'stuff' is uninitialized

Où est le terminateur nul? stuff n'est pas initialisé, il peut donc commencer par NUL ou ne contenir NUL nulle part.

En C++, vous pouvez faire ceci:

char stuff[100] = {};  // 'stuff' is initialized to all zeroes

Vous pouvez maintenant faire strcat, car le premier caractère de 'stuff' est le null-terminator, il sera donc ajouté au bon endroit.

En C, vous devez toujours initialiser le «matériel», ce qui peut être fait de différentes manières:

char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
                 // so 'stuff' is effectively ""
strcpy(stuff, "hi ");  // this initializes 'stuff' if it's not already.
33
Tim

Dans le premier cas, stuff contient des déchets. strcat exige que la destination et la source contiennent les chaînes correctes terminées par un zéro.

strcat(stuff, "hi ");

va scanner stuff pour un caractère '\0' final, où il commencera à copier "hi ". S'il ne le trouve pas, il ira à la fin du tableau et de mauvaises choses peuvent se produire de manière arbitraire (c'est-à-dire que le comportement n'est pas défini).

Une façon d'éviter le problème est la suivante:

char stuff[100];
stuff[0] = '\0';      /* ensures stuff contains a valid string */
strcat(stuff, "hi ");
strcat(stuff, "there");

Ou vous pouvez initialiser stuff à une chaîne vide:

char stuff[100] = "";

qui remplira tous les 100 octets de stuff avec des zéros (la clarté accrue vaut probablement tout problème de performances mineur).

5
Keith Thompson

De plus, je vous déconseille d'utiliser strcpy ou strcat car ils peuvent entraîner des problèmes inattendus.

Utilisez strncpy et strncat , car ils aident à prévenir les dépassements de mémoire tampon.

0

Strcat ajoute une chaîne à une chaîne existante. Si le tableau de chaînes est vide, la fin de la chaîne ('\0') ne sera pas recherchée et une erreur d'exécution sera générée.

Selon la page de manuel Linux, strcat simple est implémenté de cette façon:

   char*
   strncat(char *dest, const char *src, size_t n)
   {
       size_t dest_len = strlen(dest);
       size_t i;

       for (i = 0 ; i < n && src[i] != '\0' ; i++)
           dest[dest_len + i] = src[i];
       dest[dest_len + i] = '\0';

       return dest;
   }

Comme vous pouvez le constater dans cette implémentation, strlen(dest) ne retournera pas la longueur de chaîne correcte à moins que dest soit initialisé pour corriger les valeurs de chaîne c. Vous pouvez avoir de la chance d'avoir un tableau avec la première valeur de zéro à char stuff[100];, mais vous ne devriez pas vous en fier.

0
sung

Parce que stuff n'est pas initialisé avant l'appel à strcpy. Après que la déclaration stuff ne soit plus une chaîne vide, il s’agit de données non initialisées. 

strcat ajoute des données à la fin d'une chaîne - c'est-à-dire qu'elle trouve le terminateur nul dans la chaîne et ajoute des caractères après celle-ci. Une chaîne non initialisée n'est pas garantie d'avoir un terminateur null, donc strcat est susceptible de planter.

Si vous deviez initialiser stuff comme ci-dessous, vous pourriez effectuer les opérations suivantes:

char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");
0
shf301