C ++中signed char的负值cout

时间:2018-01-16 07:27:22

标签: c++ c++11 gcc

C ++如何处理有问题的char的负值?行为是用C ++ 11标准定义的吗?我正在使用MinGW C ++ 11编译器。看起来有符号值通过添加256转换为无符号类型,然后打印扩展的ASCII字符。

signed char a=-35;
std::cout<<a;

3 个答案:

答案 0 :(得分:5)

根据this,选择了以下重载:

template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
                                        signed char ch );

由于signed char不是chara首先使用widen转换为char

char_type widen( char c ) const;

所以你的代码相当于:

std::cout << std::cout.widen(c);
// or:
std::cout << std::use_facet< std::ctype<char> >(getloc()).widen(c)

如您所见,widen需要char,因此在实际“扩大”之前,您将从signed char转换为char

即使您从char扩展到char,行为也是实现定义的 - 标准不保证这一点。

答案 1 :(得分:2)

使用类型转换为julia> using Base.Meta: quot julia> x = :abc :abc julia> expr = quote a = [] push!(a, $(quot(x))) a end quote #= REPL[16]:2 =# a = [] #= REPL[16]:3 =# push!(a, :abc) #= REPL[16]:4 =# a end julia> eval(ans) 1-element Array{Any,1}: :abc ...

int

...或者,遵循更好的C ++编程风格(正如Christian Hackl建议的那样):

std::cout << (int)a;

这实际上没有回答你的问题(霍尔特已经回答过),但显示了问题的解决方案。

答案 2 :(得分:1)

大多数情况都是必需的行为(大部分内容仍然是必需的。)

具体来说,C ++标准说iostream与C风格的输入和输出流相关联,因此coutstdout相关联(§[narrow.stream.objects] / 3) :

  

对象cout控制输出到与stdout中声明的对象<cstdio>关联的流缓冲区。

反过来,C标准将窄字符输出定义为如果通过fputc(§7.19.3/ 12)写入:

  

字节输出函数将字符写入流,就像连续调用fputc函数一样。

fputc要求(§7.19.7.3/ 2):

  

fputc函数将c指定的字符(转换为unsigned char)写入stream指向的输出流,[...]

所以,是的,转换为unsigned char正是标准所要求的。 C标准要求从有符号到无符号(任何整数类型,包括char)的转换以下列方式发生(§6.3.1.3/ 2):

  

否则,如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。

所以是的,通过添加256将其转换为无符号(假设unsigned char可以表示0到255之间的值,这是典型的)。

因此,我们只有一部分标准尝试要求,而不是完全 - widen必须做的转换(§[locale.ctype.virtuals] / 10):

  

将char值或char值序列中最简单的合理转换应用于相应的charT值。

由于确定什么是“合理的”有点困难,因此可以对你的角色进行一些或多或少的任意映射。实际上,它显然是在没有修改的情况下将输入映射到输出(至少对于你正在编写的特定字符),但是其他转换可能属于“合理”,并且最终难以画出强硬的说法。任何特定的转变都不“合理”。

C ++(或任何其他)标准并不真正需要的另一部分是其他东西将如何解释该输出。所有语言标准都可以强制要求写入流。打开该流并将其内容解释为“扩展ASCII”(可能是ISO 8859变体之一)的其他部分显然超出了语言的控制范围(当然,或者程序中的其他任何内容)。