&c
如何在此循环以及分配c = toupper(c)
的过程中工作?
string str = "hello";
for (auto & c: str)
c = toupper(c);
你能解释一下吗?
答案 0 :(得分:1)
首先,请注意,如果std::toupper
的值为EOF
以外的其他值,则它具有未定义的行为。对于大多数编译器,char
默认为带符号类型。在典型的8位字节计算机上,这意味着如果c
的值不在ASCII范围内(从0到127),则它为负数,则得到UB。
解决该问题的一种简单方法是将参数强制转换为unsigned char
:
auto to_upper( const char c )
-> char
{
using Byte = unsigned char;
return static_cast<char>( toupper( static_cast<Byte>( c ) );
}
仍然,此功能默认情况下仅适用于ASCII字符,即字母A到Z,因为它采用C级语言环境指定的编码,默认情况下为"C"
,本质上仅限于ASCII。但至少可以避免未定义行为。因此,让我们假设您的示例使用了它,
for( auto& c : str ) c = to_upper( c );
这是基于范围的for
循环,它遍历str
中的所有项目,将引用c
绑定到每个项目并执行循环主体具有这种约束力。由于str
的项目类型为char
,因此auto
将推论为char
。因此,与编写for( char& c : str ) ...
相同。
因此,默认情况下,它会将str
中的所有ASCII字符都大写。
在Windows中,如果已经通过setlocale( LC_ALL, "" )
设置了C语言环境,则假定的编码将为Windows ANSI,并且如果str
包含编码为to_upper
的字符,将执行其大写操作正确地。这意味着在Windows中可以将其用于例如大写挪威语字符串,例如"Blåbærsyltetøy"
,前提是Windows的语言环境是使用Windows ANSI Western的语言环境。
在* nix中,调用setlocale
无济于事,因为用户的本机语言环境将指定UTF-8编码,其中ASCII以外的每个字符都表示为两个或多个字节,大于127。
答案 1 :(得分:0)
auto & c
等效于char & c
,它是对字符串中每个字符的引用。更新引用的值会更改字符串中的引用字符。
上面的代码的结果将是一个大写的字符串。