2013-10-25 44 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并为其分配一个新的char值(如:*str = c),程序会崩溃。但str初始化时指向buf,所以我不知道为什么会发生这种情况。

* 编辑:这是怎么了调用该函数:* char *p = "string goes here"; normalize(p, strlen(p));

+0

你可能会传递一个字符串常量(文字)到'normalize'吗?告诉我们你如何调用这个函数。 – Kninnug

+1

你是否传递了一些字符串作为参数? – ouah

+0

我这样调用它:char * p =“string goes here”; normalize(p,strlen(p)); – Ryan

回答

0

我没有看到你在isspace为(前)在使用前初始化分组。

1

p被宣布为char *p = "Some string";,因为p是初始化字符串常量的指针你不能用p调用你的函数。这意味着您无法修改p的内容,并且尝试这样做会导致未定义的行为(这是导致段错误的原因)。但是,当然,您可以将p指向其他位置,即指向可写字符序列。可以将p声明为一个字符数组。你可以初始化它就像你用指针声明做了,但是数组声明使得串写:

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

记住,数组是不可修改的左值,所以你将无法分配到p,但您可以更改p[i]中的内容,这正是您想要的内容。

除此之外,请注意,您的代码在第一次循环迭代中使用了垃圾值prev,因为您从不初始化它。因为您只使用prev来测试它是否为空格,所以也许更好的方法是使用标记prev_is_space,而不是显式存储前一个字符。这将使启动循环变得容易,您只需将prev_is_space初始化为0,或者如果有前导空格(这实际上取决于您希望函数的行为方式),则为1。