2013-10-25 7 views
0

Я пишу функцию normalize, которая подготавливает строку для обработки. Это код:* str = c дает мне ошибку сегментации

/* The normalize procedure examines a character array of size len 
in ONE PASS and does the following: 
1) turns all upper-case letters into lower-case ones 
2) turns any white-space character into a space character and, 
shrinks any n>1 consecutive spaces into exactly 1 space only 
3) removes all initial and final white-space characters 

Hint: use the C library function isspace() 
You must do the normalization IN PLACE so that when the procedure 
returns, the character array buf contains the normalized string and 
the return value is the length of the normalized string. 
    */ 
int normalize(char *buf, /* The character array containing the string to be normalized*/ 
      int len /* the size of the original character array */) 
{ 
    /* exit function and return error if buf or len are invalid values */ 
if (buf == NULL || len <= 0) 
    return -1; 

char *str = buf; 
char prev, temp; 
len = 0; 

/* skip over white space at the beginning */ 
while (isspace(*buf)) 
    buf++; 


/* process characters and update str until end of buf */ 
while (*buf != '\0') { 
    printf("processing %c, buf = %p, str = %p \n", *buf, buf, str); 

    /* str might point to same location as buf, so save previous value in case str ends up changing buf */ 
    temp = *buf; 

    /* if character is whitespace and last char wasn't, then add a space to the result string */ 
    if (isspace(*buf) && !isspace(prev)) { 
    *str++ = ' '; 
    len++; 
    } 

    /* if character is NOT whitespace, then add its lowercase form to the result string */ 
    else if (!isspace(*buf)) { 
    *str++ = tolower(*buf); 
    len++; 
    } 

    /* update previous char and increment buf to point to next character */ 
    prev = temp; 
    buf++; 
} 


/* if last character was a whitespace, then get rid of the trailing whitespace */ 
if (len > 0 && isspace(*(str-1))) { 
    str--; 
    len--; 
} 

/* append NULL character to terminate result string and return length */ 
*str = '\0'; 
return len; 

}

Однако я получаю ошибку сегментации. Я сузил проблему до этой линии:

*str++ = *buf;

Более конкретно, если я пытаюсь почтительными Облами и присвоить ему новое значение обугленного (например: *str = c) программы даст сбой. Однако str был инициализирован в начале, чтобы указать на buf, поэтому я не знаю, почему это происходит.

* EDIT: Это, как я вызываю функцию: * char *p = "string goes here"; normalize(p, strlen(p));

+0

Возможно, вы передаете строчную константу (литерал), чтобы «нормализовать»? Покажите нам, как вы вызываете функцию. – Kninnug

+1

Вы передаете строковый литерал в качестве аргумента? – ouah

+0

Я называю это следующим: char * p = "string here here"; normalize (p, strlen (p)); – Ryan

ответ

0

Я не вижу, где вы инициализирован пред прежде чем использовать его в isspace (предыдущая).

1

Вы не можете назвать вашу функцию с p когда p был объявлен как char *p = "Some string";, так как p указатель инициализируется строковой константы. Это означает, что вы не можете изменить содержимое p, и попытка сделать это приводит к неопределенному поведению (это причина segfault). Тем не менее, вы можете, конечно, сделать p точкой в ​​другом месте, а именно, с возможностью записи символов.

В качестве альтернативы вы можете объявить p массивом символов. Вы можете инициализировать его так же, как вы сделали с объявлением указателя, но декларация массива делает строку записываемой:

char p[] = "Some string"; 
normalize(p, strlen(p)); 

Помните, что массивы не изменяемые л-значения, так что вы не сможете назначить p, но вы можете изменить содержимое в p[i], что и есть то, что вы хотите.

Кроме того, обратите внимание, что ваш код использует prev с значениями мусора в первой итерации цикла, потому что вы никогда не инициализируете его. Поскольку вы используете только prev, чтобы проверить, является ли это пространством, возможно, лучший подход состоял бы в том, чтобы иметь флаг prev_is_space, а не явно хранить предыдущий символ. Это упростит запуск цикла, вам просто нужно инициализировать prev_is_space до 0 или 1, если есть ведущие пробелы (это действительно зависит от того, как вы хотите, чтобы ваша функция вела себя).

Смежные вопросы