1

我在这里有几行:

#include <stdio.h>

char *tolower(char *data)
{
    char *p = data;
    while(*p)
    {
        printf("nilai p : %c\n",*p);
            if(*p >= 'A' && *p <= 'Z')
            {
                *p += ('a' - 'A');
            }
        p++;
    }
    return p;

}

int main()
{

    char *a = "HajAR BleH";
    char *b = tolower(a);

    printf("nilai b : %s\n",b);
    printf("nilai a - A : %d\n",'a' - 'A');
return 0;
}

接下来,编译,在 gdb 上运行,并跟踪分段

xxx@aaa:/tmp$ gcc -o aa aa.c --debug
xxx@aaa:/tmp$ gdb -q aa
Reading symbols from /tmp/aa...done.
(gdb) r
Starting program: /tmp/aa 
nilai p : H

Program received signal SIGSEGV, Segmentation fault.
0x0804841e in tolower (data=0x804855e "HajAR BleH") at aa.c:11
11                  *p += ('a' - 'A');
(gdb) 

问题

1.我认为*p += ('a' - 'A');会等于'H' += ('a' - 'A')和等于72 += 32 但是,不小心分段错误,怎么会这样?

2.为什么需要添加 ('a' - 'A') 来降低char/byte降低?

暂时就这些了,先谢谢了

4

5 回答 5

7

您正在尝试修改字符串文字。改变:

char *a = "HajAR BleH";

到:

char a[] = "HajAR BleH";

此外,已经有一个名为 tolower() 的标准库函数,您实际上应该在代码中使用它。调用你自己的函数别的东西。

于 2011-05-16T10:30:25.277 回答
4

最可能的原因SEGV是编译器已放置a在只读内存中,因为它允许使用字符串文字。

尝试将a的定义更改为:

char a[] = "HajAR BleH";

就风格而言,已经存在一个名为 的标准函数tolower,它做一些不同的事情(将一个字符转换为小写)。考虑到这一点,我建议:

  1. 给你的函数一个不同的名字以避免混淆;
  2. tolower在您的实现中使用将一个字符转换为小写。
于 2011-05-16T10:30:56.093 回答
2

段错误的原因是您正在尝试修改驻留在只读内存中的字符串文字,从而导致未定义的行为。

尝试改变

char *a = "HajAR BleH";

char a[] = "HajAR BleH";
于 2011-05-16T10:30:35.940 回答
0

除了只读内存的问题外,您还需要返回data而不是p. 当您的循环完成时,p指向空终止符。

于 2011-05-16T10:32:58.767 回答
0

1:基本上你的代码是正确的,但是你试图修改一个常量字符串(char *a应该 reda const char *a)。您必须创建另一个可以修改的字符数组。

2:('a' - 'A')计算小写字符和大写字符之间 ascii 值的“差异”(32)。

于 2011-05-16T10:36:23.857 回答