你们知道为什么下面的代码在运行时会崩溃吗?
char* word;
word = new char[20];
word = "HeLlo";
for (auto it = word; it != NULL; it++){
*it = (char) tolower(*it);
我正在尝试将 char* (字符串)小写。我正在使用视觉工作室。
谢谢
你们知道为什么下面的代码在运行时会崩溃吗?
char* word;
word = new char[20];
word = "HeLlo";
for (auto it = word; it != NULL; it++){
*it = (char) tolower(*it);
我正在尝试将 char* (字符串)小写。我正在使用视觉工作室。
谢谢
你无法it
与NULL
. 相反,您应该*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));
}
您设置word
为指向字符串文字,但文字是只读的,因此当您分配给*it
. 您需要在动态分配的内存中复制它。
char *word = new char[20];
strcpy(word, "HeLlo");
同样在您的循环中,您应该比较*it != '\0'
. 字符串的结尾由作为空字节的字符指示,而不是由空指针指示。
给定代码(在我写这个的时候):
char* word;
word = new char[20];
word = "HeLlo";
for (auto it = word; it != NULL; it++){
*it = (char) tolower(*it);
此代码以两种不同的方式具有未定义的行为,并且如果仅文本数据略有不同,则也会以第三种方式具有 UB:
缓冲区溢出。如果指针在地址范围的末尾回绕,则
继续条件it != NULL
不会出现。false
it
修改只读存储器。
指针word
设置为指向char
字符串文字的第一个,然后循环遍历该字符串并分配给每个char
.
将可能的负值传递给tolower
.
分类函数需要一个非负参数,char
或者特殊值EOF
。"HeLlo"
在假设 ASCII 或无符号char
类型的情况下,这适用于字符串。但一般来说,例如使用 string "Blåbærsyltetøy"
,直接将每个char
值传递给tolower
将导致传递负值;正确调用ch
of 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 ); }
关于如何使用空终止的 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);
它崩溃是因为您正在修改字符串文字。
有一个专门的函数用于
strupr
使字符串大写和strlwr
使字符串小写。
这是一个使用示例:
char str[ ] = "make me upper";
printf("%s\n",strupr(str));
char str[ ] = "make me lower";
printf("%s\n",strlwr (str));