C ++转换参数初始化问题

问题描述 投票:0回答:1

我正在尝试将字符串转换为小写形式,并使用std :: transform和std :: tolower将其存储在另一个变量中。我首先尝试过:

string str1("Hello");
string lowerStr1;
transform(str1.begin(), str1.end(), lowerStr1.begin(), ::tolower);
cout << lowerStr1 << endl;

但是,lowerStr1不包含任何内容。用str1初始化lowerStr1后,得到了所需的结果。我想知道这背后的直觉。有人可以解释为什么在这种情况下lowerStr1应该被初始化吗?

c++ transform tolower
1个回答
1
投票

lowerStr1为空,并且transform不会在其中插入元素。您可以使用back_inserter,例如

transform(str1.begin(), str1.end(), back_inserter(lowerStr1), ::tolower);

0
投票

这是因为您对std::transform的调用在逻辑上等效于以下代码:

auto b=str1.begin();
auto e=str1.end();
auto p=lowerStr1.begin();

while (b != e)
{
       *p=tolower(*b);
       ++b;
       ++e;
}

但是lowerStr1,是一个完全为空的字符串。粗略地说,lowerStr1.begin()为您提供了一个指向空字符串的指针。因此,写入该指针,并加重侮辱性伤害,使其加重并继续写入该指针,将导致不确定的行为,内存损坏以及崩溃的可能性很小。

您不会通过抓住指向该字符串的指针,然后在该指针中进行划线来添加内容。使用push_back()或insert()方法,有几种正确的方法。您也可以使用执行此操作的迭代器,例如std::back_insert_iterator,可以与std::transform一起使用。


0
投票

通用算法不会更改容器的大小。您需要使用以特殊方式实现operator=的迭代器适配器。因此,您可以使用back_inserter(lowerStr1)来确保lowerStr1被扩展为trasform()进行分配。

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
  string str1("Hello");
  string lowerStr1;
  transform(str1.begin(), str1.end(), std::back_inserter(lowerStr1), ::tolower);
  cout << lowerStr1 << endl;
}

© www.soinside.com 2019 - 2024. All rights reserved.