Inverser une chaîne en C
je sais que cela a été demandé des milliers de fois mais je ne peux pas trouver l'erreur dans mon code. Quelqu'un pourrait-il gentiment signaler ce que je fais mal?
#include <stdlib.h>
#include <string.h>
void reverseString(char *myString){
char temp;
int len = strlen(myString);
char *left = myString;
// char *right = &myString[len-1];
char *right = myString + strlen(myString) - 1;
while(left < right){
temp = *left;
*left = *right; // this line seems to be causing a segfault
*right = temp;
left++;
right--;
}
}
int main(void){
char *somestring = "hello";
printf("%sn", somestring);
reverseString(somestring);
printf("%s", somestring);
}
6 réponses
le problème est ici
char *somestring = "hello";
somestring pointe vers la chaîne littérale "hello". le standard C++ ne garantit pas cela, mais sur la plupart des machines, ce sont des données en lecture seule, donc vous ne serez pas autorisé à les modifier.
déclarer cette façon, au lieu
char somestring[] = "hello";
en fin de compte, il serait plus propre de l'inverser en place, comme suit:
#include <stdio.h>
#include <string.h>
void
reverse(char *s)
{
int a, b, c;
for (b = 0, c = strlen(s) - 1; b < c; b++, c--) {
a = s[b];
s[b] = s[c];
s[c] = a;
}
return;
}
int main(void)
{
char string[] = "hello";
printf("%s\n", string);
reverse(string);
printf("%s\n", string);
return 0;
}
votre solution est essentiellement une version sémantiquement plus grande de celle-ci. Comprendre la différence entre un pointeur et un tableau. La norme stipule explicitement que le comportement d'une telle opération (modification du contenu d'une chaîne littérale) n'est pas défini. Vous devriez également voir extrait de esquimau:
lorsque vous initialisez un tableau de caractères avec un chaîne de caractères:
char string[] = "Hello, world!";
vous finissez avec un tableau contenant la chaîne, et vous pouvez modifier le contenu du tableau au contenu de votre cœur:
string[0] = 'J';
cependant, il est possible d'utiliser des constantes de chaîne (le terme formel est string literals) à d'autres endroits dans votre code. Comme ce sont des tableaux, le compilateur génère des pointeurs vers leurs premiers éléments lorsqu'ils sont utilisés dans des expressions, comme d'habitude. C'est, si vous dites
char *p1 = "Hello";
int len = strlen("world");
c'est presque comme si vous aviez dit
char internal_string_1[] = "Hello";
char internal_string_2[] = "world";
char *p1 = &internal_string_1[0];
int len = strlen(&internal_string_2[0]);
ici, les tableaux nommés internal_string_1 et internal_string_2 sont censés suggérer le fait que le compilateur génère en fait de petits tableaux temporaires chaque fois que vous utilisez une constante de chaîne dans votre code. Cependant, le fait subtil est que les tableaux qui sont `derrière" les constantes de chaîne ne sont pas nécessairement modifiables. En particulier, le compilateur peut les stocker en mémoire en lecture seule. Par conséquent, si vous écrivez
char *p3 = "Hello, world!";
p3[0] = 'J';
votre programme peut crash, parce qu'il peut essayer de stocker une valeur (dans ce cas, le caractère 'J') dans une mémoire non inscriptible.
la morale est que chaque fois que vous construisez ou modifiez des cordes, vous devez vous assurer que la mémoire dans laquelle vous construisez ou modifiez les cordes est accessible par écrit. Cette mémoire devrait être soit un tableau que vous avez alloué, soit une mémoire que vous avez affectée dynamiquement par les techniques que nous verrons dans le prochain chapitre. Assurez-vous qu'aucune partie de votre programme sera jamais essayer de modifier un string qui est en fait l'un des tableaux non nommés et non consignés que le compilateur a généré pour vous en réponse à l'une de vos constantes de string. (La seule exception est l'initialisation du tableau, parce que si vous écrivez à un tel tableau, vous écrivez au tableau, et non à la chaîne de caractères littérale que vous avez utilisée pour initialiser le tableau.) "
Vous invoquez un comportement non défini en essayant de modifier une zone mémoire potentiellement en lecture seule (les caractères littéraux des chaînes sont implicitement const
-- c'est ok pour les lire mais pas écrire). Créez une nouvelle chaîne et retournez-la, ou passez un tampon assez grand et écrivez la chaîne inversée à elle.
Vous pouvez utiliser le code suivant
#include<stdio.h>
#include<string.h>
#include<malloc.h>
char * reverse(char*);
int main()
{
char* string = "hello";
printf("The reverse string is : %s", reverse(string));
return 0;
}
char * reverse(char* string)
{
int var=strlen(string)-1;
int i,k;
char *array;
array=malloc(100);
for(i=var,k=0;i>=0;i--)
{
array[k]=string[i];
k++;
}
return array;
}
votre logique semble correcte. Au lieu d'utiliser des pointeurs, il est plus propre de traiter avec char[]
.