如何在std::for_each中使用std::toupper
How to use std::toupper in std::for_each?
我正在尝试使用std::toupper函数将字符串的小写字符转换为大写字符,并且我正在使用std::for_each算法迭代字符串中的字符。
#include <iostream>
#include <string>
#include <algorithm>
#include <locale>
std::string convert_toupper(std::string *x) {
return std::toupper(*x, std::locale());
}
int main() {
std::string x ("example");
std::for_each(x.begin(), x.end(), convert_toupper);
}
当我编译这段代码时,我得到这个错误:
In file included from /usr/include/c++/4.8/algorithm:62:0,
from me2.cpp:3:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; _Funct = std::basic_string<char> (*)(std::basic_string<char>*)]’:
me2.cpp:13:52: required from here
/usr/include/c++/4.8/bits/stl_algo.h:4417:14: error: invalid conversion from ‘char’ to ‘std::basic_string<char>*’ [-fpermissive]
__f(*__first);
^
使用std::toupper和std::for_each从小写到大写的字符转换的正确方法是什么?
A string
基本上是char
s的容器。当你迭代一个string
的时候,你每次只迭代一个char
。因此,传递给for_each
的函子将被char
调用,而不是string*
,因此出现错误:
invalid conversion from ‘char’ to ‘std::basic_string<char>*
正确的实现应该是:
std::for_each(x.begin(), x.end(), std::toupper);
然而,这不会有任何作用。toupper
的返回值将被忽略,并且该函数没有副作用。如果您真的想要将字符串转换成它的大写版本,您必须使用std::transform
:
std::transform(x.begin(), x.end(), x.begin(), std::toupper);
或者,提供区域设置:
char locale_upper(char c) { return std::toupper(c, std::locale()); }
std::transform(x.begin(), x.end(), x.begin(), locale_upper);
或者在c++ 11中:
std::transform(x.begin(), x.end(), x.begin(), [](char c){
return std::toupper(c, std::locale());
});
此时,您不妨使用for
-loop:
for (char& c : x) {
c = std::toupper(c, std::locale());
}
在<locale>
中,您已经有了std::ctype::toupper
函数将小写字符串转换为大写。函数调用有点棘手,但它非常紧凑:
std::use_facet<std::ctype<char>>(std::locale()).toupper(&x[0], &x[0] + x.size());
下面是使用std::for_each
和std::toupper
将小写字符串转换为大写字符串的一种方法。重要的是要记住将lambda中的参数设置为字符引用,如(char& ch)
。
#include <algorithm> // for_each
#include <cctype> // toupper
#include <iostream> // cout
#include <string> // string
int main()
{
std::string s{ "This is a test" };
std::cout << s << 'n';
std::for_each(s.begin(), s.end(),[] (char& ch) { ch = std::toupper(ch); } );
std::cout << s << 'n';
return 0;
}
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么 std::unique 不调用 std::sort?
- Std::string::toupper作用于输入字符串
- 如何在std::for_each中使用std::toupper