我正在尝试将字符串转换为小写形式,并使用std :: transform和std :: tolower将其存储在另一个变量中。我首先尝试过:
string str1("Hello");
string lowerStr1;
transform(str1.begin(), str1.end(), lowerStr1.begin(), ::tolower);
cout << lowerStr1 << endl;
但是,lowerStr1不包含任何内容。用str1初始化lowerStr1后,得到了所需的结果。我想知道这背后的直觉。有人可以解释为什么在这种情况下lowerStr1应该被初始化吗?
lowerStr1
为空,并且transform
不会在其中插入元素。您可以使用back_inserter
,例如
transform(str1.begin(), str1.end(), back_inserter(lowerStr1), ::tolower);
这是因为您对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
一起使用。
通用算法不会更改容器的大小。您需要使用以特殊方式实现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;
}