char
类型而不是unsigned char
类型来实例化basic_[io]stream及其所有变体。根据char
是有符号还是无符号,你可能会在像get()这样的操作中发生溢出和下溢,这将导致涉及的变量具有实现定义的值。另一个例子是当你想要使用它的put
函数将字节未格式化地输出到ostream时。任何想法吗?
注意:我仍然不太确定。如果你知道确定的答案,确实可以发表回复。
char
类型而不是unsigned char
类型来实例化basic_[io]stream及其所有变体。根据char
是有符号还是无符号,你可能会在像get()这样的操作中发生溢出和下溢,这将导致涉及的变量具有实现定义的值。另一个例子是当你想要使用它的put
函数将字节未格式化地输出到ostream时。((un)?signed)? char
进行任何算术运算都会被提升为(unsigned)? int
。只需执行+c
即可触发提升(这是一元+的主要用途)。这与C不同:在C中,对((un)?signed)? char
的值(而非lvalue)的任何使用都将使其提升。 - curiousguyiostream
类的目的是读取和/或写入字符流,如果你仔细想想,字符只是抽象实体,只能使用字符编码来表示。C++标准非常努力地避免固定字符编码,只说“声明为字符(char
)的对象应足够大,可以存储实现基本字符集中的任何成员”,因为它不需要强制“实现基本字符集”来定义C++语言;标准可以将使用哪种字符编码的决定留给实现(编译器和STL实现),并且只注明char
对象表示某些编码中的单个字符。char
对象“足够大,可以存储实现基本字符集中的任何成员”(请注意,这明确禁止可变长度编码),那么实现甚至可以选择一种根本不兼容任何常见编码的表示基本拉丁文的编码!
char
、signed char
和unsigned char
类型在名称中共享“char”,这很令人困惑,但重要的是要记住char
不属于与signed char
和unsigned char
相同的基本类型家族。 signed char
属于带符号整数类型的家族:
有四种带符号整数类型:“signed char”、“short int”、“int”和“long int”。
unsigned char
是无符号整数类型家族的一员:
对于每个有符号整数类型,都存在一个相应的(但不同的)无符号整数类型: "unsigned char", "unsigned short int", "unsigned int" 和 "unsigned long int",...
char
、signed char
和 unsigned char
这三种类型之间唯一的共同点是它们“占用相同数量的存储空间并具有相同的对齐要求”。因此,您可以使用 reinterpret_cast
将 char *
转换为 unsigned char *
,以确定执行字符集中字符的数字值。
回答您的问题,STL 使用 char
作为默认类型的原因是标准流用于读取和/或写入由 char
对象表示的字符流,而不是整数(signed char
和 unsigned char
)。使用 char
而不是数值是分离关注点的一种方式。
char
和 signed char
不一样吗?哇,+1!正如 Scott Meyers 所说,Aha!http://www.artima.com/cppsource/top_cpp_aha_moments.html - Gabrielistream
和 fread
(来自 C 语言)都可以从流中读取字符,但是 fread
使用 unsigned char
,而 istream
使用 char
。 - qbt937char代表字符,unsigned char代表原始数据的字节,signed char则代表带符号的数据。
标准并未规定在实现char时使用signed还是unsigned - 这取决于编译器。标准只规定“char”将足以在您的系统上容纳字符 - 字符在那些日子里的方式,即没有UNICODE。
使用“char”表示字符是标准的方法。使用unsigned char是一种hack,尽管它会在大多数平台上与编译器的char实现匹配。
ios_base::binary
的作用)。如果使用unsigned char,我们将不必担心负char值,并始终获得正值。这似乎会更好。 - Johannes Schaub - litb我认为this评论已经很好地解释了。引用如下:
signed char和unsigned char是算术整数类型,就像int和unsigned int一样。另一方面,char明确旨在成为“I/O”类型,表示平台上某些不透明的系统特定基本数据单元。我会按照这种精神使用它们。