C++ 到下/上字符指针

C++ tolower/toupper char pointer

本文关键字:字符 指针 到下 C++      更新时间:2023-10-16

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

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

我正在尝试小写字符*(字符串(。我正在使用Visual Studio。

谢谢

您无法将itNULL进行比较。相反,您应该将*it''进行比较。或者更好的是,使用std::string,永远不要担心它:-(

总之,在循环访问 C 样式字符串时。你应该循环,直到你看到的角色是一个''。迭代器本身永远不会NULL,因为它只是指向字符串中的一个位置。迭代器具有可以与NULL进行比较的类型这一事实是您不应直接接触的实现细节。

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

编辑:正如@Cheers和hth所指出的。- Alf,如果给定负值,tolower可能会中断。所以可悲的是,我们需要添加一个强制转换,以确保如果你给它输入拉丁-1 编码数据或类似数据,它不会中断。

这应该有效:

char word[] = "HeLlo";
for (auto it = word; *it != ''; ++it) {
    *it = tolower(static_cast<unsigned char>(*it));
}

您正在将word设置为指向字符串文本,但文本是只读的,因此当您分配给*it时,这会导致未定义的行为。您需要在动态分配的内存中复制它。

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

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

给定代码(当我写这篇文章时(:

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

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

  • 缓冲区溢出。
    在指针it在地址范围的末尾环绕之前,不会false继续条件it != NULL(如果有(。

  • 修改只读内存。
    指针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 字符串和 poitner 来解决您的问题,已经有两个不错的答案。 为了完整起见,我向您建议一种使用 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("%sn",strupr(str));

char str[ ] = "make me lower";
printf("%sn",strlwr (str));