2010-04-13 27 views
6

He visto muchas preguntas sobre eso en StackOverflow, pero leer las respuestas no lo resolvió, probablemente porque soy un novato total en la programación de C. Aquí está el código:Devolver un puntero a una matriz de caracteres en C

#include <stdio.h> 

char* squeeze(char s[], char c); 

main() 
{ 
    printf("%s", squeeze("hello", 'o')); 
} 

char* squeeze(char s[], char c) 
{ 
    int i, j; 

    for(i = j = 0; s[i] != '\0'; i++) 
    if(s[i] != c) 
     s[j++] = s[i]; 
    s[j] = '\0'; 

    return s; 
} 

Se compila y obtengo un error de segmentación cuando lo ejecuto. He leído this preguntas frecuentes sobre el retorno de matrices y he intentado con la técnica "estática" que se sugiere allí, pero todavía no he podido hacer que el programa funcione. ¿Podría alguien señalar exactamente qué le pasa y qué debería estar prestando atención en el futuro?

+2

¿Qué estás tratando de hacer? –

+0

@snitko: ¿Dónde está el tipo de devolución de 'main()'? –

Respuesta

6

El primer argumento pasado a la función de compresión es read-only literal de cadena "hello", que está intentando modificar.

lugar pasarle un array de caracteres modificables:

char str[] = "hello"; 
printf("%s", squeeze(str, 'o')); 
+1

También se podría invocar el principio de menos sorpresa para sugerir hacer una copia de la cadena, en su lugar. Si paso un char * en una función que devuelve char *, es posible que no espere que esté modificando la matriz en contexto. (Los diseñadores de API suelen ser descuidados en cuanto a si usan _const_). –

3

El problema es que constante matriz de caracteres "hello" no se puede modificar correctamente por la función a la que se transmitió. Por lo tanto, basta con que estás pasando una matriz no constante (por ejemplo, haciendo un array local que se pasa, siempre y cuando el resultado no se necesita fuera de la persona que llama squeeze 's):

int main() 
{ 
    char xxx[] = "hello"; 
    printf("%s", squeeze(xxx, 'o')); 

    return 0; 
} 

Usted esperaríamos que dicha constante solo se pudiera pasar a un argumento const (para que el compilador mismo pudiera decirle qué está haciendo mal), pero, por desgracia, eso no es lo que exige el estándar C (presumiblemente por razones de compatibilidad con versiones anteriores) con código histórico).

+1

No tiene nada de temporal, la cadena se almacena en la memoria "estática". –

+0

Buen punto (y por palabras de mi parte, permítanme reformular). –

3

Esto está tratando de modificar los datos no modificables.

"hello" es una cadena constante, almacenada en la memoria en alguna parte. Lo que estás tratando de hacer, entonces, es cambiarlo, y eso generalmente no está permitido. No veo a qué te refieres con "estático", pero lo que quieres es algo así como ...

int main() 
{ 
    char hello_str[16]; 
    strcpy(hello_str, "hello"); 
    printf("%s", squeeze(hello_str, 'o')); 
} 
Cuestiones relacionadas