c++ std::格式行为不同,在有符号字符/无符号字符之间

fae0ux8s  于 2023-02-17  发布在  其他
关注(0)|答案(2)|浏览(85)

此行为是否符合预期或标准(使用VC编译器)?

示例1(有符号字符):

char s = 'R'
std::cout << s << std::endl;         // Prints R.
std::cout << std::format("{}\n", s); // Prints R.

示例2(无符号字符):

unsigned char u = 'R';
std::cout << u << std::endl;         // Prints R.
std::cout << std::format("{}\n", u); // Prints 82.

std::format的第二个示例中,u被打印为82而不是R,这是一个错误还是预期行为?
如果不使用std::format,而只使用std::cout,则在两个示例中都得到R

xqnpmsa8

xqnpmsa81#

这是有意的,并在标准中作了规定。
charunsigned char基本上都是数值类型。通常只有char具有表示字符的附加含义。例如,没有unsigned char字符串文字。如果使用unsigned char(通常别名为std::uint8_t),则通常假定它表示数值(或者内存的原始字节,尽管std::byte是更好的选择)。
因此,默认情况下为unsigned char选择数字解释,为char选择字符解释是有意义的,在这两种情况下,都可以用{:c}作为字符解释的说明符,用{:d}作为数字解释的说明符。
我认为operator<<的行为是非直观的,但这已经存在了很长时间,可能无法改变。
还要注意,signed char是与charunsigned char完全不同的类型,并且char是有符号整数类型还是无符号整数类型是由实现定义的(但总是与signedunsigned char不同)。
如果您使用signed char,它也会被默认解释为数字,原因与unsigned char相同。

czfnxgou

czfnxgou2#

在第二个示例std::format中,它被打印为82而不是'R',这是一个问题还是标准?
这是标准根据format.string.std(https://eel.is/c++draft/tab:format.type.int)定义的行为:
| 类型|意义|
| - ------|- ------|
| ...|...|
| c|将字符static_­cast<charT>(value)复制到输出。如果value不在charT的可表示值范围内,则引发format_­error。|
| d|to_­chars(first, last, value) .|
| ...|...|
| 无|与d相同。[* 注8*:如果格式化参数类型为charTbool,则默认值分别为cs。- * 结束注解 *]|
对于整数类型,如果未指定 type 选项,则d将是默认值。由于unsigned char是整数类型,因此它将被解释为整数,其值将是由std::to_chars转换的值。
(除charT类型和bool类型外,默认 * 类型 * 选项为cs

相关问题