2010-04-13 2 views
6

Я видел много вопросов по этому поводу в StackOverflow, но чтение ответов не прояснило это для меня, вероятно, потому, что я новичок в программировании на C. Вот код:Вернуть указатель на массив символов в 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; 
} 

Он компилируется, и я получаю ошибку сегментации, когда я запускаю его. Я прочитал this о возвращении массивов и попробовал «статическую» технику, которая предлагается там, но все еще не могла заставить программу работать. Может ли кто-нибудь указать на то, что с ним не так, и что я должен уделять в будущем?

+2

Что вы пытаетесь сделать? –

+0

@snitko: Где тип возврата 'main()'? –

ответ

6

1-й аргумент, переданный функции сжатия, представляет собой строковый литерал read-only"hello", который вы пытаетесь изменить.

Вместо передать его изменяемый массив символов:

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

Можно также назвать принцип наименьшего удивления, предлагая вместо этого сделать копию строки. Если я передаю char * в функцию, которая возвращает char *, я не могу ожидать, что он изменит массив на месте. (Дизайнеры API часто неаккуратно используют ли они _const_.) –

3

Проблема заключается в том, что константа char array "hello" может быть неправильно изменена функцией, которой она была передана. Таким образом, просто убедитесь, что вы передаете непостоянный массив (например, путем создания локального массива будет приняты, пока в результате не требуется вне вызывающих squeeze «s):

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

    return 0; 
} 

You 'd ожидаем, что такая константа может быть передана только в аргумент const (так что сам компилятор может сказать вам, что вы делаете неправильно), но, увы, это не то, что соответствует стандарту C (по-видимому, из соображений обратной совместимости с историческим кодом).

+1

В этом нет ничего временного, строка хранится в «статической» памяти. –

+0

Хорошая точка (и по формулировке со своей стороны позвольте мне перефразировать). –

3

Это пытается изменить немодифицируемые данные.

«hello» - это постоянная строка, хранящаяся в памяти где-то. То, что вы пытаетесь сделать, это изменить его, и это обычно не допускается. Я не понимаю, что вы подразумеваете под «статикой», но то, что вы хотите, будет ...

int main() 
{ 
    char hello_str[16]; 
    strcpy(hello_str, "hello"); 
    printf("%s", squeeze(hello_str, 'o')); 
} 
Смежные вопросы