我正在使用变换算法和std :: toupper来实现这一点,但这可以在一行中完成吗?
transform(s.begin(), s.end(), ostream_iterator<string>(cout, "\n"),std::toupper);
我得到错误,所以我必须为此创建一个函数并使用transform调用它或者我可以使用一些适配器吗?
答案 0 :(得分:9)
使用ostream_iterator<char>
代替ostream_iterator<string>
:
transform(s.begin(),s.end(),ostream_iterator<char>(cout,"\n"),std::toupper);
std::transform
转换每个字符并将其传递给输出迭代器。这就是为什么输出迭代器的type参数应该是char
而不是std::string
。
顺便说一句,每个角色都会打印在换行符上。那是你要的吗?如果没有,请不要通过"\n"
。
-
注意:您可能必须使用::toupper
代替std::toupper
。
见这些
答案 1 :(得分:4)
首先,如果你想输出char
s(以及所有char
s),你将会
需要使用ostreambuf_iterator<char>
,而不是
ostream_iterator<string>
。而且ostreambuf_iterator<char>
表达了
比ostream_iterator<char>
更能满足您的需求;你是
直接输出char
,而不是格式化任何内容。
(ostream_iterator
使用格式化的<<
运算符。)
其次,请注意并非总是有一对一的翻译
从低到高(例如'ß'
映射到中的两个字符序列"SS"
大写),所以std::transform
不能真正用于完成这项工作
正确。 (当然,它不处理像你这样的多字节编码
UTF-8正确。)除了最简单的用途,你需要一些东西
更复杂。但即使是最简单的情况:
std::toupper
被重载:其中一个重载是模板,其中
有两个参数,另一个是一个单一的函数
int
;这两个都不会直接在这里工作,transform
也是如此
模板也意味着重载决议和模板类型
扣除即使他们这样做也行不通。所以基本上,你必须添加
一些东西。如果您可以使用2参数模板函数
添加足够的限定符并使用boost::bind
或类似绑定的东西
第二个论点,但它几乎和写一个简单的文本一样多
toupper
功能性论证你的自我。你不能使用单身
参数形式(如果包含,可以明确访问)
<ctype.h>
并使用::toupper
)因为它具有未定义的行为
当你调用它时,你使用char
作为参数:你必须转换
首先是char
到unsigned char
(当然,除非是普通char
在你正在使用的实现中没有签名 - 总而言之
您的代码将被移植到的实现。)