字符转换函数 std::isupper() & std::islower() C++17

Cod*_*ity 6 c++ c++17

我创建了一个简单的程序来检查用户输入的字母是大写还是小写,然后使用std::isupper()andstd::islower()函数将小写转换为大写,将大写转换为小写。在运行代码时,我得到了数字形式的字符转换,而不是预期的大写/小写等价物。这是为什么?

#include <iostream>

int main()
{
    char letter {};

    std::cout << "Enter a letter:";

    std::cin >> letter;

    if (std::isupper(letter))
    {
        std::cout << "You entered an uppercase letter"
                     "\n"
                     "the lowercase equivalent is:"
                  << std::tolower(letter);
    }

    if (std::islower(letter))    
    {
        std::cout << "You entered a lowercase letter"
                     "\n"
                     "the uppercase equivalent is:"
                  << std::toupper(letter);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

下面是一个输出示例:

Enter a letter:F
You entered an uppercase letter.
The lowercase equivalent is:102

Enter a letter:f
You entered a lowercase letter.
The uppercase equivalent is:70
Run Code Online (Sandbox Code Playgroud)

Yks*_*nen 9

std::tolowerstd::toupper返回int,而不是char由于它是 C 的遗留起源int因此选择了某些要求,请参见脚注)。

您可以将其转换回 char 以获得预期结果:

static_cast<char>(std::tolower(letter));
Run Code Online (Sandbox Code Playgroud)

或者您可以char之前将结果保存在一个变量中(如果您需要在其他地方转换后者):

letter = std::tolower(letter);
std::cout << letter;
Run Code Online (Sandbox Code Playgroud)

注意:正如Peter在评论中所注意到的,有要求std::tolower并且std::toupper要求使用比实际需要的类型更大的类型。在下面引用它:

它们还被指定为能够接受和返回EOF- 一个不能表示为 char 但可以表示为 int 的值。C++ iostreams(当然不是 C 的遗留,是 templated 的特化std::basic_istream)有一个get()没有参数的函数,它从流中读取一个字符,并返回一个大于正在读取的字符类型的整数类型。它是能够从文件中读取单个字符并处理错误情况的机制的一部分。

  • `toupper()` 和 `tolower()` 返回 `int` 不仅仅是“C 的遗产”。它们还被指定为能够接受并返回“EOF”——一个不能表示为“char”但可以表示为“int”的值。C++ iostreams(当然没有来自 C 的遗留,是模板化 `std::basic_istream` 的特化)有一个不带参数的 `get()` 函数,它从流中读取字符,并返回大于字符类型的整数类型正在阅读。它是能够从文件中读取单个字符并处理错误情况的机制的一部分。 (3认同)

Moh*_*lah 0

if(std::isupper(letter))
{

  std::cout<<"You entered an uppercase letter"<<"\n"

  "the lowercase equivalent is:" << (char)std::tolower(letter);
}

if (std::islower(letter))

{

  std::cout<<"You entered a lowercase letter"<<"\n"

  "the uppercase equivalent is:" << (char)std::toupper(letter);

}

    return 0;

}
Run Code Online (Sandbox Code Playgroud)

  • @Code_Infinity 注意:此答案中使用的 C 风格转换通常被认为是 C++ 中的不良风格。最好不要养成使用它的习惯。 (6认同)
  • @Nazim C 风格的强制转换很危险。您基本上是在告诉编译器“我不关心类型安全,尽一切努力使这种类型成为另一种类型”。C++ 风格的强制转换具有更大程度的控制,例如“static_cast”不会意外地放弃常量。这在[softwareengineering.se]的[这个问题](https://softwareengineering.stackexchange.com/questions/50442/c-style-casts-or-c-style-casts)中有很好的解释 (5认同)
  • @hyde c 风格转换和 c++ 风格转换之间有什么区别。实际上,它们以输出方式做同样的事情。这是一个编码问题,即“不要在 C++ 中使用 C,反之亦然”。能稍微解释一下吗,谢谢。 (2认同)