86 votes

Est-il possible de modifier une chaîne de caractères en C?

J'ai eu du mal pendant quelques heures avec toutes sortes de C tutoriels et livres liés à des pointeurs, mais ce que je veux vraiment savoir c'est si il est possible de modifier un pointeur de char une fois, il a été créé.

C'est ce que j'ai essayé:

char *a = "This is a string";
char *b = "new string";

a[2] = b[1]; // Causes a segment fault

*b[2] = b[1]; // This almost seems like it would work but the compiler throws an error.

Donc, est-il possible de modifier les valeurs à l'intérieur des chaînes plutôt que le pointeur d'adresses?

Merci

EDIT:

Merci à tous pour vos réponses. Il fait plus de sens maintenant. Il permet en particulier de sens pourquoi parfois ça marchait très bien et d'autres fois pas de travail. Parce que parfois, j'aimerais passer un pointeur de char et d'autres fois un tableau de char (char tableau a bien fonctionné).

167voto

Carson Myers Points 11135

Lorsque vous écrivez une "chaîne" dans votre code source, il est écrit directement dans l'exécutable, car cette valeur doit être connue au moment de la compilation (il existe des outils disponibles pour tirer un logiciel à part et de trouver toute la plaine des chaînes de texte dans leur). Lorsque vous écrivez char *a = "This is a string", l'emplacement de la "Ceci est une chaîne" est dans le fichier exécutable, et l'emplacement des points de, est dans l'exécutable. Les données dans le fichier exécutable de l'image est en lecture seule.

Ce que vous devez faire (comme les autres réponses ont souligné) est de créer de la mémoire dans un endroit qui n'est pas en lecture seule, sur le tas, ou dans le cadre de la pile. Si vous déclarez un local de tableau, alors l'espace est faite sur la pile pour chaque élément de ce tableau, et la chaîne littérale (qui est stocké dans le fichier exécutable) est copié sur l'espace dans la pile.

char a[] = "This is a string";

vous pouvez également copier les données manuellement par l'allocation de la mémoire sur le tas, et ensuite à l'aide d' strcpy() pour copier une chaîne de caractères littérale dans cet espace.

char *a = malloc(256);
strcpy(a, "This is a string");

Chaque fois que vous allouer de l'espace à l'aide de malloc() n'oubliez pas d'appeler free() quand vous avez fini avec elle (lire: fuite de mémoire).

Fondamentalement, vous devez garder une trace de l'endroit où vos données. Chaque fois que vous écrivez une chaîne de caractères dans votre code source, cette chaîne est en lecture seule (sinon vous seriez susceptible de modifier le comportement de l'exécutable--imaginez si vous avez écrit char *a = "hello"; puis modifiés a[0] de 'c'. Puis, quelque part d'autre a écrit printf("hello");. Si vous avez été autorisé à changer le premier caractère de l' "hello", et votre compilateur ne sont stockées qu'une fois (il devrait), alors printf("hello"); sortie cello!)

31voto

Jonathan Maddison Points 603

Non, vous ne pouvez pas le modifier car la chaîne peut être stockée dans une mémoire en lecture seule. Si vous voulez le modifier, vous pouvez utiliser un tableau à la place, par exemple

 char a[] = "This is a string";
 

Ou alternativement, vous pouvez allouer de la mémoire en utilisant malloc, par exemple

 char *a = malloc(100);
strcpy(a, "This is a string");
free(a); // deallocate memory once you've done
 

17voto

Jeff Ober Points 3314

Beaucoup de gens sont confus au sujet de la différence entre char* et char[] en conjonction avec des littéraux de chaîne en C. Lorsque vous écrivez:

char *foo = "hello world";

...vous sont effectivement pointant vers toto constant bloc de mémoire (en fait, ce que le compilateur ne "hello world" dans ce cas est dépendant de l'implémentation.)

À l'aide de char[] au lieu de cela indique au compilateur que vous souhaitez créer un tableau et le remplir avec le contenu, le "hello world". foo est un pointeur vers le premier indice du tableau de char. Ils sont tous les deux pointeurs de char, mais seulement char[] pointe vers un localement affectées et mutable bloc de mémoire.

7voto

Naveen Points 37095

La mémoire pour a & b n'est pas allouée par vous. Le compilateur est libre de choisir un emplacement de mémoire en lecture seule pour stocker les caractères. Donc, si vous essayez de changer, cela peut entraîner une erreur grave. Je vous suggère donc de créer vous-même un tableau de caractères. Quelque chose comme: char a[10]; strcpy(a, "Hello");

6voto

Sweeney Points 366

Il semble que votre question a été répondu, mais maintenant vous pourriez vous demander pourquoi char *a = "String" est stocké dans la mémoire en lecture seule. Eh bien, il est en fait pas défini par le standard c99, mais la plupart des compilateurs choisir de cette façon pour des cas comme:

printf("Hello, World\n");

standard c99(pdf) [page 130, section 6.7.8]:

La déclaration:

char s[] = "abc", t[3] = "abc";

définit la "plaine" char tableau des objets de s et t, dont les éléments sont initialisés avec la chaîne de caractères littéraux. Cette déclaration est identique à char

s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };

Le contenu de ces tableaux sont modifiables. D'autre part, la déclaration

char *p = "abc";

définit p de type "pointeur vers char" et l'initialise à pointer vers un objet de type "tableau de char" avec une longueur de 4 dont les éléments sont initialisés avec un littéral de chaîne de caractères. Si une tentative est faite pour utilisez p pour modifier le contenu du tableau, le comportement est indéfini.

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