【问题标题】:Transforming a string to lowercase in a new string在新字符串中将字符串转换为小写
【发布时间】:2014-11-04 22:26:40
【问题描述】:

字符串的转换可以用

std::transform(s.begin(), s.end(), s.begin(), ::toupper);

但是将其转换为新的修改副本的最佳方法是什么?

试过了:

string s1="text",s2;
std::transform(s1.begin(), s1.end(), s2.begin(), ::toupper);

但它在运行时因“分段错误”而失败

我设法做到了:

string s1="text",s2;
s2 = s1;
std::transform(s2.begin(), s2.end(), s2.begin(), ::toupper);

当然,您可以创建一个逐个字符的函数,但我认为这不是最佳的,而且我没有从中学到任何东西......

【问题讨论】:

  • 你需要std::back_inserter()
  • 您应该使用std::toupper 并确保如果char 已签名,则不会将负值传递给它,以免您有未定义的行为。
  • @chris 这个例子实际上是从cppreference 站点复制粘贴的,所以 std::string 可以有无符号字符或负值吗?
  • @Columbo 你为什么删除你的答案?
  • @clickstefan 因为我不喜欢它。我发布了帮助答案,但认为它没有帮助。

标签: c++


【解决方案1】:

std::transform 不知道容器,不会为您插入新元素。
std::back_inserter 提供了一个迭代器,为push_backs 赋值:

// DO NOT use this
std::transform(s1.begin(), s1.end(), std::back_inserter(s2), ::toupper);
//                                   ^^^^^^^^^^^^^^^^^^^^^^

但是,您不应使用全球版本的toupper,因为它已被弃用。
还有你先have to cast the argument to unsigned char,不然很容易遇到未定义的行为。

transform 似乎不适合这里,因为您需要一个 lambda;使用

for (auto ch : s1)
    s2 += std::toupper((unsigned char)ch);

Demo.

【讨论】:

  • 所以unsigned char 问题需要使用 lambda 吗?所以这使得transform(str->begin(), str->end(), str->begin(), ::tolower); 也无效?
  • @clickstefan 首先需要一个 lambda 才能调用 std::tolower。是的,transform 的行是无效的。问题是简单地用char 调用(非本地版本的)tolower 通常是错误的。
【解决方案2】:

除非需要使用std::transform,否则您可以使用:

string s1="text";
string s2 = s1;
for ( auto& ch : s2 )
   ch = toupper((unsigned char)ch);

【讨论】:

  • 哦,我完全忽略了你的循环与我的不同 :) 无论如何,代码仍然缺少演员表。
  • 我不明白强制转换的必要性。 std::toupper() 接受 int 作为输入。
  • std::transform 不是必须的,但这仍然会在实际转换之前创建 s1 的副本
【解决方案3】:

我不太明白为什么其中一个答案说

// DO NOT use this
std::transform(s1.begin(), s1.end(), std::back_inserter(s2), ::toupper);
//                                   ^^^^^^^^^^^^^^^^^^^^^^

push_back()std::string 的一种方法,可以将std::transformstd::back_inserter 一起使用

#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <string>

int main() {
  std::string s1 = "ABCDEFG";
  std::string s2;
  std::transform(s1.begin(), s1.end(), std::back_inserter(s2),
                 [](unsigned char uc) { return std::tolower(uc); });
  std::cout << s2 << std::endl; // abcdefg
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-11
    • 2018-01-13
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    相关资源
    最近更新 更多