0

你们知道为什么下面的代码在运行时会崩溃吗?

char* word;
word = new char[20];
word = "HeLlo"; 
for (auto it = word; it != NULL; it++){        
    *it = (char) tolower(*it);

我正在尝试将 char* (字符串)小写。我正在使用视觉工作室。

谢谢

4

6 回答 6

6

你无法itNULL. 相反,您应该*it'\0'. 或者更好的是,使用std::string它而不用担心它:-)

总之,当循环一个 C 风格的字符串时。您应该循环直到您看到的字符'\0'. 迭代器本身永远不会是NULL,因为它只是指向字符串中的一个位置。迭代器具有可以比较的类型这一事实是NULL您不应该直接触及的实现细节。

此外,您正在尝试写入字符串文字。这是一个禁忌:-)。

编辑:正如@Cheers 和hth 所指出的。- Alf,tolower如果给定负值,可能会中断。很遗憾,我们需要添加一个演员表,以确保如果您向其提供拉丁 1 编码数据或类似数据,它不会中断。

这应该有效:

char word[] = "HeLlo";
for (auto it = word; *it != '\0'; ++it) {
    *it = tolower(static_cast<unsigned char>(*it));
}
于 2015-11-23T21:05:31.507 回答
4

您设置word为指向字符串文字,但文字是只读的,因此当您分配给*it. 您需要在动态分配的内存中复制它。

char *word = new char[20];
strcpy(word, "HeLlo");

同样在您的循环中,您应该比较*it != '\0'. 字符串的结尾由作为空字节的字符指示,而不是由空指针指示。

于 2015-11-23T21:08:08.677 回答
3

给定代码(在我写这个的时候):

char* word;
word = new char[20];
word = "HeLlo"; 
for (auto it = word; it != NULL; it++){        
    *it = (char) tolower(*it);

此代码以两种不同的方式具有未定义的行为,并且如果仅文本数据略有不同,则也会以第三种方式具有 UB:

  • 缓冲区溢出。如果指针在地址范围的末尾回绕,则
    继续条件it != NULL不会出现。falseit

  • 修改只读存储器。
    指针word设置为指向char字符串文字的第一个,然后循环遍历该字符串并分配给每个char.

  • 将可能的负值传递给tolower.
    分类函数需要一个非负参数,char或者特殊值EOF"HeLlo"在假设 ASCII 或无符号char类型的情况下,这适用于字符串。但一般来说,例如使用 string "Blåbærsyltetøy",直接将每个char值传递给tolower将导致传递负值;正确调用chof typechar(char) tolower( (unsigned char)ch ).

此外,代码存在内存泄漏,通过分配一些内存new然后忘记它。

编码明显意图的正确方法:

using Byte = unsigned char;

auto to_lower( char const c )
    -> char
{ return Byte( tolower( Byte( c ) ) ); }

// ...
string word = "Hello";
for( char& ch : word ) { ch = to_lower( ch ); }
于 2015-11-23T21:18:35.817 回答
1

关于如何使用空终止的 c-strings 和 poitners 解决您的问题,已经有两个很好的答案。为了完整起见,我建议您使用 C++ 字符串的方法:

string word;           // instead of char* 
//word = new char[20]; // no longuer needed: strings take care for themseves
word = "HeLlo";        //  no worry about deallocating previous values: strings take care for themselves
for (auto &it : word)  // use of range for, to iterate through all the string elements      
    it = (char) tolower(it);
于 2015-11-23T21:19:36.960 回答
1

它崩溃是因为您正在修改字符串文字。

于 2015-11-23T22:20:08.243 回答
0

有一个专门的函数用于 strupr使字符串大写和strlwr使字符串小写。

这是一个使用示例:

char str[ ] = "make me upper";
printf("%s\n",strupr(str));


char str[ ] = "make me lower";
printf("%s\n",strlwr (str));
于 2017-11-03T09:29:02.403 回答