想要将一个std::string字符串转换成小写,经搜索使用了std::transform来实现,可是偶然发现了打印string与string.c_str()会有不同的结果。
代码如下:
string strTitle("TEST");
string strLowercase;
std::transform(strTitle.begin(), strTitle.end(), strLowercase.begin(), ::tolower);
printf("strLowercase.c_str() is %s", strLowercase.c_str());std::cout<<"string strLowercase is "<<strLowercase<<endl;
结果竟然是:
strLowercase.c_str() is test
string strLowercase is
单步调试也发现strLowercase的打印结果为空,而strLowercase.c_str()打印的是预期结果。
把第三行代码改成下面的就没问题了:
std::transform(strTitle.begin(), strTitle.end(), std::back_inserter(strLowercase), ::tolower);
对std::transform不熟,对std::back_inserter也不了解,以后有空还是要研究一下才行。
一些资料:
关于std::transform,有两种可能的实现方式:
First version
template<class InputIt, class OutputIt, class UnaryOperation>
OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first,
UnaryOperation unary_op)
{
while (first1 != last1) {
*d_first++ = unary_op(*first1++);
}
return d_first;
}
Second version
template<class InputIt1, class InputIt2,
class OutputIt, class BinaryOperation>
OutputIt transform(InputIt first1, InputIt last1, InputIt first2,
OutputIt d_first, BinaryOperation binary_op)
{
while (first1 != last1) {
*d_first++ = binary_op(*first1++, *first2++);
}
return d_first;
}
std::back_inserter的定义:
template< class Container >
std::back_insert_iterator<Container> back_inserter( Container& c );
解释:back_inserter is a convenience function template that constructs a std::back_insert_iterator for the container c with the type deduced from the type of the argument.
Parameters
c - container that supports a push_back operation
Return value
A std::back_insert_iterator which can be used to add elements to the end of the container c
可以看到back_inserter函数会返回一个std::back_insert_iterator类型的迭代器,用于在容器c后面增加元素。最上面的代码为什么要使用std::back_inserter就很明显了。
另外一个发现:std::back_inserter(strLowercase)是可以用于push_back操作的,而错误的代码中有strLowercase.begin()没报错,说明string也能执行push_back操作是不是?一搜果然是的
参考:
http://en.cppreference.com/w/cpp/algorithm/transform
http://en.cppreference.com/w/cpp/iterator/back_inserter