C++ tolower/toupper 字符指针
C++ tolower/toupper char pointer
你们知道为什么下面的代码会在运行时崩溃吗?
char* word;
word = new char[20];
word = "HeLlo";
for (auto it = word; it != NULL; it++){
*it = (char) tolower(*it);
我正在尝试将 char*(字符串)小写。我正在使用 visual studio.
谢谢
您无法将 it
与 NULL
进行比较。相反,您应该将 *it
与 '[=14=]'
进行比较。或者更好的是,使用 std::string
并且永远不用担心 :-)
总而言之,当遍历 C 风格的字符串时。你应该循环直到你看到的字符是一个'[=14=]'
。迭代器本身永远不会是 NULL
,因为它只是指向字符串中的一个位置。迭代器具有可以与 NULL
进行比较的类型这一事实是您不应直接接触的实现细节。
此外,您正在尝试写入字符串文字。这是一个禁忌:-)。
编辑:
正如@Cheers 和 hth 所指出的。 - Alf,tolower
可以在给定负值时中断。很遗憾,我们需要添加一个强制转换,以确保如果您向它提供 Latin-1 编码数据或类似数据,它不会中断。
这应该有效:
char word[] = "HeLlo";
for (auto it = word; *it != '[=10=]'; ++it) {
*it = tolower(static_cast<unsigned char>(*it));
}
您将 word
设置为指向字符串文字,但文字是只读的,因此当您分配给 *it
时会导致未定义的行为。您需要在动态分配的内存中复制它。
char *word = new char[20];
strcpy(word, "HeLlo");
同样在你的循环中你应该比较*it != '[=13=]'
。字符串的结尾由字符表示为空字节,而不是指针为空。
给出的代码(我正在写这篇文章):
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
。在 ASCII 或无符号 char
类型的假设下,这适用于字符串 "HeLlo"
。但总的来说,例如使用字符串 "Blåbærsyltetøy"
,直接将每个 char
值传递给 tolower
将导致传递负值; char
类型的 ch
的正确调用是 (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 字符串和指针来解决您的问题,已经有两个不错的答案。为了完整起见,我向您推荐一种使用 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));
你们知道为什么下面的代码会在运行时崩溃吗?
char* word;
word = new char[20];
word = "HeLlo";
for (auto it = word; it != NULL; it++){
*it = (char) tolower(*it);
我正在尝试将 char*(字符串)小写。我正在使用 visual studio.
谢谢
您无法将 it
与 NULL
进行比较。相反,您应该将 *it
与 '[=14=]'
进行比较。或者更好的是,使用 std::string
并且永远不用担心 :-)
总而言之,当遍历 C 风格的字符串时。你应该循环直到你看到的字符是一个'[=14=]'
。迭代器本身永远不会是 NULL
,因为它只是指向字符串中的一个位置。迭代器具有可以与 NULL
进行比较的类型这一事实是您不应直接接触的实现细节。
此外,您正在尝试写入字符串文字。这是一个禁忌:-)。
编辑:
正如@Cheers 和 hth 所指出的。 - Alf,tolower
可以在给定负值时中断。很遗憾,我们需要添加一个强制转换,以确保如果您向它提供 Latin-1 编码数据或类似数据,它不会中断。
这应该有效:
char word[] = "HeLlo";
for (auto it = word; *it != '[=10=]'; ++it) {
*it = tolower(static_cast<unsigned char>(*it));
}
您将 word
设置为指向字符串文字,但文字是只读的,因此当您分配给 *it
时会导致未定义的行为。您需要在动态分配的内存中复制它。
char *word = new char[20];
strcpy(word, "HeLlo");
同样在你的循环中你应该比较*it != '[=13=]'
。字符串的结尾由字符表示为空字节,而不是指针为空。
给出的代码(我正在写这篇文章):
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
。在 ASCII 或无符号char
类型的假设下,这适用于字符串"HeLlo"
。但总的来说,例如使用字符串"Blåbærsyltetøy"
,直接将每个char
值传递给tolower
将导致传递负值;char
类型的ch
的正确调用是(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 字符串和指针来解决您的问题,已经有两个不错的答案。为了完整起见,我向您推荐一种使用 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));