Invertendo una stringa in C
-
23-09-2019 - |
Domanda
So che questo è stato chiesto migliaia di volte, ma non riesco proprio a trovare l'errore nel mio codice. Qualcuno potrebbe gentilmente precisare quello che sto facendo male?
#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("%s\n", somestring);
reverseString(somestring);
printf("%s", somestring);
}
Soluzione
il problema è qui
char *somestring = "hello";
punti someString alla stringa letterale "ciao". standard C ++ non gurantee questo, ma sulla maggior parte delle macchine, questo sarà di sola lettura dei dati, in modo da non sarà permesso di modificarlo.
dichiararlo questo modo invece
char somestring[] = "hello";
Altri suggerimenti
In definitiva, sarebbe più pulito per invertire tale tendenza in atto, in questo modo:
#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;
}
La vostra soluzione è essenzialmente una versione semanticamente più grande di questo. Capire la differenza tra un puntatore e un array. La norma afferma esplicitamente che la behviour di un'operazione tale (modifica del contenuto di una stringa letterale) è indefinito. Si dovrebbe anche vedere questo estratto da Eskimo:
Quando si inizializza un array di caratteri con una costante stringa:
char string[] = "Hello, world!";
si finisce con un array contenente la stringa, ed è possibile modificare i contenuti della matrice al contenuto del vostro cuore:
string[0] = 'J';
Tuttavia, è possibile utilizzare le costanti di stringa (il termine formale è stringhe) in altri posti nel codice. Dato che sono gli array, il compilatore genera i puntatori ai loro primi elementi quando sono usati nelle espressioni, come al solito. Cioè, se si dice
char *p1 = "Hello";
int len = strlen("world");
è quasi come se avessi detto
char internal_string_1[] = "Hello";
char internal_string_2[] = "world";
char *p1 = &internal_string_1[0];
int len = strlen(&internal_string_2[0]);
Qui, gli array di nome internal_string_1 e internal_string_2 dovrebbero suggerire il fatto che il compilatore è in realtà generando piccoli array temporaneo ogni volta che si utilizza una stringa costante nel codice. Tuttavia, il fatto sottile è che le matrici che sono `` dietro '' le costanti di stringa non sono necessariamente modificabili. In particolare, il compilatore può riporli in sola lettura memoria. Pertanto, se si scrive
char *p3 = "Hello, world!";
p3[0] = 'J';
il programma potrebbe bloccarsi, perché può tentare di memorizzare un valore (in questo caso, il carattere 'J') nella memoria nonwritable.
La morale è che ogni volta che si sta costruendo o modificando le stringhe, è necessario fare in modo che la memoria si sta costruendo o modificando in è scrivibile. Quel ricordo dovrebbe essere o una matrice che avete assegnato, o qualche memoria che hai allocata dinamicamente dalle tecniche che vedremo nel prossimo capitolo. Assicurarsi che nessuna parte del vostro programma potrà mai tentare di modificare una stringa che è in realtà uno dei senza nome, gli array non scrivibili che il compilatore ha generato per voi in risposta a una delle vostre costanti stringa. (L'unica eccezione è l'inizializzazione array, perché se si scrive a una tale varietà, si sta scrivendo alla matrice, non la stringa letterale, che è stato utilizzato per inizializzare l'array.) "
Si sta invocando un comportamento indefinito, cercando di modificare una zona potenzialmente memoria a sola lettura (stringhe letterali sono implicitamente const
- è ok per leggerli, ma non a scrivere di loro). Creare una nuova stringa e restituirlo, o passare un buffer di grandi dimensioni abbastanza e scrivere la stringa invertita ad esso.
È possibile utilizzare il seguente codice
#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;
}
Lo prendo chiamando strrev () è fuori questione?
La logica sembra corretto. Invece di usare puntatori, è più pulito di trattare con char[]
.