【问题标题】:C++ std::transform() and toupper() ..why does this fail?C++ std::transform() 和 toupper() ..为什么会失败?
【发布时间】:2010-12-02 03:18:24
【问题描述】:

我有 2 个 std::string。我只想,给定输入字符串:

  1. 每个字母都大写
  2. 将大写字母分配给输出字符串。

这是怎么回事:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), std::back_inserter(out), std::toupper);

但这不会(导致程序崩溃)?

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), out.begin(), std::toupper);

因为这行得通(至少在同一个字符串上:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), s.begin(), std::toupper);

【问题讨论】:

  • 在我的情况下(gcc 4.7),这些示例都无法正确编译,我猜是因为std::toupper 已被两个参数变体重载(由locale.h 提供)。我必须明确地投射它:std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))std::toupper);

标签: c++ string stl transform


【解决方案1】:

out 中没有空格。 C++ 算法不会自动增长它们的目标容器。您必须自己腾出空间,或使用插入器适配器。

要在out 中腾出空间,请执行以下操作:

out.resize(s.length());

[edit] 另一种选择是使用此构造函数创建大小正确的输出字符串。

std::string out(s.length(), 'X');

【讨论】:

  • 这和(都是字符串)有什么区别:std::string s2(s1); std::transform(s2.begin(), s2.end(), s2.begin(), std::toupper); ?哦,我只是回答了我自己的问题,我认为,在第一种情况下,它只是调整字符串的大小。但在第二种情况下,我认为它是等价的?
  • 查看以下内容:stackoverflow.com/questions/7131858/… cplusplus.com/reference/iterator/back_inserter(虽然我可能会使用调整自己的大小来提高速度)
【解决方案2】:

我想说out.begin() 返回的迭代器在空字符串的几个增量之后无效。在第一个++ 之后是==out.end(),那么下一个增量之后的行为是未定义的。

毕竟这正是插入迭代器的用途。

【讨论】:

  • 不会 .begin() 立即等于 .end() 对于空字符串,而不是在第一个增量之后?
【解决方案3】:

这就是反向插入器的含义:它将元素插入到容器中。使用 begin(),您将迭代器传递给空容器并修改无效的迭代器。

很抱歉 - 我的编辑干扰了您的 cmets。我第一次不小心发错了。

【讨论】:

  • std::transform 将函数应用于字符串的每个字符。
猜你喜欢
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-04
  • 2021-06-08
  • 1970-01-01
  • 2010-10-22
相关资源
最近更新 更多