使用 std::transform 将字符串转换为全部大写字母
我正在使用变换算法和 std::toupper 来实现这一点,但是这可以像这样在一行中完成吗?
transform(s.begin(), s.end(), ostream_iterator<string>(cout, "\n"),std::toupper);
我在这方面遇到错误,所以我是否必须为此创建一个一元函数并使用转换来调用它,或者我可以使用一些适配器?
I'm using transform algorithm and std::toupper to achieve this, but can this be done in one line, like this ?
transform(s.begin(), s.end(), ostream_iterator<string>(cout, "\n"),std::toupper);
I get error on this, so do I have to make a unary function for this and call it with transform or I can use some adaptors ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用
ostream_iterator
而不是ostream_iterator
:std::transform
转换每个字符并将其传递给输出迭代器。这就是为什么输出迭代器的类型参数应该是char
而不是std::string
。顺便说一下,每个字符都会打印在换行符上。这就是你想要的吗?如果不是,请不要传递
"\n"
。--
注意: 您可能必须使用
::toupper
而不是std::toupper
。请参阅这些
Use
ostream_iterator<char>
instead ofostream_iterator<string>
:std::transform
transforms each character and pass it to the output iterator. That is why the type argument of the output iterator should bechar
instead ofstd::string
.By the way, each character will be printed on a newline. Is that what you want? If not, don't pass
"\n"
.--
Note : You may have to use
::toupper
instead ofstd::toupper
.See these
首先,如果您想输出
char
(以及所有char
),您将需要使用
ostreambuf_iterator
,而不是ostream_iterator
。并且ostreambuf_iterator
表示比
ostream_iterator
更好你想要的;你是直接输出
char
,不格式化任何内容。(
ostream_iterator
使用<<
运算符进行格式化。)其次,请注意,并不总是存在一对一的翻译
从下到上(例如
'ß'
映射到两个字符序列"SS"
大写),所以
std::transform
不能真正用于完成这项工作正确。 (当然,它不处理多字节编码,例如
UTF-8 正确。)对于除了最简单的用途之外的所有用途,您需要一些东西
更复杂。但即使对于最简单的情况:
std::toupper
也被重载:重载之一是模板,它接受两个参数,另一个是一个接受单个参数的函数
int
;两者都不能直接在这里工作,事实上transform
是模板也意味着重载解析和模板类型
即使他们这样做了,扣除也不会起作用。所以基本上,你必须添加
某物。如果您满足以下条件,则可以使用 2 个参数模板函数
添加足够的限定符并使用
boost::bind
或类似绑定的东西第二个参数,但它几乎和写一个简单的文本一样多
toupper
函数论证你自己。而且你不能使用单一参数形式(如果包含,则可以明确访问
并使用::toupper
) 因为它具有未定义的行为,如果当你调用它时,你使用
char
作为参数:你必须转换首先将
char
转换为unsigned char
(当然,除非是普通的char
在您正在使用的实现中以及所有中都未签名
您的代码将被移植到的实现)。
First, if you want to output
char
s (and all of thechar
s), you'llneed to use
ostreambuf_iterator<char>
, and notostream_iterator<string>
. Andostreambuf_iterator<char>
expressesbetter what you want than
ostream_iterator<char>
; you'reoutputting
char
s directly, not formatting anything.(
ostream_iterator
uses the<<
operator, which formats.)Second, be aware that there is not always a one to one translation of
lower to upper (e.g.
'ß'
maps to the two character sequence"SS"
inupper case), so
std::transform
can't really be used to do the jobcorrectly. (And of course, it doesn't handle multibyte encodings like
UTF-8 correctly.) For all but the simplest uses, you need something
more complicated. But even for the simplest cases:
std::toupper
is overloaded: one of the overloads is a template, whichtakes two arguments, and the other is a function which takes a single
int
; neither will work directly here, and the fact thattransform
isalso a template means that overload resolution and template type
deduction won't work even if they did. So basically, you have to add
something. It's possible to use the 2 argument template function if you
add enough qualifiers and use
boost::bind
or something similar to bindthe second argument, but it's almost as much text as writing a simple
toupper
functional argument your self. And you can't use the singleargument form (which can be unambiguously accessed if you include
<ctype.h>
and use::toupper
) because it has undefined behavior ifyou use a
char
as the argument when you call it: you have to convertthe
char
tounsigned char
first (unless, of course, plainchar
isunsigned in the implementation you are using—and in all
implementations to which your code will ever be ported).