2 votes

Copie de chaînes de caractères en C

Je suis en train d'apprendre les chaînes de caractères en c. J'utilise code::blocks comme compilateur, même si ce n'est pas seulement pour le c. Donc, le problème avec le code ci-dessous est que la sortie pour string2 est les 5 caractères stockés plus la sortie de string1. Je vais vous montrer :

#include <stdio.h>
#include <string.h>          /* make strncpy() available */

int main()
{
char string1[]= "To be or not to be?";
char string2[6];

/* copy first 5 characters in string1 to string2 */
strncpy (string2, string1, 5);

printf("1st string: %s\n", string1);
printf("2nd string: %s\n", string2);
return 0;
}

La sortie est :

1st string contains: To be or not to be? 
2nd string contains: To be To be or not to be?

Si vous voulez mon avis, c'est beaucoup plus que 5 caractères...

10voto

hexa Points 4942

De la strncpy page de manuel :

Aucun caractère nul n'est implicitement ajouté à la fin de la destination, de sorte que la destination ne sera terminée par un caractère nul que si la longueur de la chaîne C dans la source est inférieure à num.

Puisque la chaîne originale est d'une longueur supérieure à 5, aucun NULL n'est ajouté.

Comme d'autres l'ont souligné, pour ajouter un peu de sécurité :

strncpy (string2, string1, sizeof(string2));
string2[sizeof(string2)-1] = '\0';

Notez que si string2 est obtenu par un malloc() :

char * string2 = malloc(123); //sizeof(string2) == sizeof(void *) and not 123

Et le code ci-dessus échouerait.

Dans un souci d'exhaustivité, voici le code : http://ideone.com/eP4vd

3voto

Felice Pollano Points 20105

Vous ne terminez pas la chaîne 2 par ' \0 ', donc le printf déborde. Essayez de le faire :

memset(string2,0,6);

avant d'utiliser string2. ou, puisque vous savez que vous copiez 5 caractères, après strncpy :

string2[5] ='\0';

pour que vous terminiez correctement la chaîne.

faites attention au fait que vous devez mettre ' \0 après exactement le nombre de caractères que vous avez copiés, sinon vous verrez des déchets même au milieu de la chaîne.

1voto

Gdogg Points 147

En fait, les deux chaînes sont sur la pile l'une à côté de l'autre en mémoire, et il n'y a pas de terminateur nul après la chaîne 2, donc quand elle s'imprime, elle imprime le "To be" de la chaîne 2. string2 + valeur aléatoire d'un octet ( string2[5] ) + string1 ("To be or not to be") avant de tomber sur un octet nul.

Si cette valeur aléatoire d'un octet était égale à 0, il s'arrêterait et vous obtiendriez l'impression attendue.

0voto

Mihai Maruseac Points 10647

Votre string2 ne contient pas \0 cette chaîne n'est donc pas terminée. Lorsque vous l'imprimez, elle sort de ses limites et imprime tout ce qu'elle y trouve jusqu'à ce qu'elle trouve un caractère \0 .

Après chaque strncpy vous devez insérer manuellement un \0 si vous voulez avoir une chaîne correctement terminée.

0voto

user411313 Points 1920

Strncpy a des limites, voir ci-dessus. Jetez un coup d'oeil à sprintf comme

sprintf( string2, "%.*s", sizeof(string2)-1, string1 );

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X