【问题标题】:Capitalize the first letter, lower case the rest第一个字母大写,其余小写
【发布时间】:2013-11-29 21:38:29
【问题描述】:

我要求用户输入他们的姓名,并且我想自动格式化姓名,以便无论他们如何输入姓名,它都会显示为首字母大写,其余字母小写。例如,如果他们输入“joHN”,程序仍会将他们的姓名输出为“John”。

我有以下代码用于他们的姓名输入:

string name;
cout << "Please enter your first name: ";
cin >> name;

我假设我将不得不使用 toupper 和 tolower 命令,但我真的不确定如何编写一些东西来调整字符串中的每个字符。

【问题讨论】:

  • 仅对大多数回答者的评论:我认为建议基于迭代器和其他 C++ 机器的 STL 算法对于询问上/下函数的人来说不是一个好的答案。他/她是 C++ 新手。这就是为什么我没有提到std::transform(),这是迄今为止最优雅的解决方案。
  • @Manu343726,没错,但并不是每个来到这里的人都会是一个完整的“新手”。

标签: c++ lowercase capitalize tolower toupper


【解决方案1】:

标准库提供了 C 函数 std::toupper()std::tolower(),它们返回指定 ASCII 字符的大写/小写。所以你的问题可以通过一个简单的 for 循环来解决:

if( !name.empty() )
{
    name[0] = std::toupper( name[0] );

    for( std::size_t i = 1 ; i < name.length() ; ++i )
        name[i] = std::tolower( name[i] );
}

【讨论】:

  • !name.empty()name.size() &gt; 0 效率更高
  • @Alex。谢谢。我们正在稍微完善答案。这似乎是一个 wiki :)
  • 还有等效的 C++ 标准函数 std::toupperstd::tolower,它们是 std::ctype 方面各自方法的包装器。
  • 当我尝试这个时,我收到错误“'length' undeclared (first use this function)。”我试着搜索这个,但结果是空的。这是因为我没有为字符串名称分配最大长度值吗?
  • @user2999339 std::string::length()std::string 的成员函数。没有理由因为它不起作用,除非你没有使用std::string
【解决方案2】:

最简单的解决方案可能是先将整个单词变成小写,然后将第一个字符变成大写。

C++ 在标准库中有一些nice algorithms。为此,我建议 std::transformstd::tolower。最后一部分当然还有std::toupper

if (!name.empty())
{
    std::transform(std::begin(name), std::end(name), std::begin(name),
                   [](char const& c)
                   {
                      return std::tolower(c);
                   });

    name[0] = std::toupper(name[0]);
}

【讨论】:

【解决方案3】:

另一种快速解决方案

#include <algorithm>
#include <string> 

if (!name.empty()) // Edit : Add the verification
{
   std::transform(name.begin(), name.end(), name.begin(), ::tolower);
   name[0] = std::toupper(name[0]);
}

【讨论】:

  • 作为@M.M.在我的回答中指出,这会调用 UB
  • 我认为要让它真正发挥作用,我必须在第 6 行(name[0]...)和第 7 行(std::transform...)之间切换。
  • 你说的很对,错了见谅!
【解决方案4】:

假设开头没有空格,可以使用std::toupper()std::tolower()

for (size_t i = 0; i < name.length(); i++)
    name[i] = i==0? std::toupper(name[i]) : std::tolower(name[i]);

更长的代码更高效:

if (name.length()>0)
{
    name[0] = std::toupper(name[0]) ;
    for (size_t i = 1; i < name.length(); i++)
        name[i] = std::tolower(name[i]);
}

最后,此代码跳过第一个空格(如果存在)

std::string capital(std::string name)
{
    if (!name.empty())
    {
        auto i = name.begin();

        while (i != name.end() && std::isspace(*i))
            ++i;

        if (i == name.end())
            return name;

        *i = std::toupper(*i++);

        std::transform(i, name.end(), i, ::tolower);
    }

    return name;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多