为什么fstream.read和fstream.write使用字符而不是无符号字符? 我知道,代码> >()和代码>和代码>(或)代码>我们可以直接从文件中读取文件,并在文件中写入字节,并且我被教导在C++中等价于字节是代码>未签名char < />代码,为什么他们使用 char < /Case>指针作为参数?< /p>

为什么fstream.read和fstream.write使用字符而不是无符号字符? 我知道,代码> >()和代码>和代码>(或)代码>我们可以直接从文件中读取文件,并在文件中写入字节,并且我被教导在C++中等价于字节是代码>未签名char < />代码,为什么他们使用 char < /Case>指针作为参数?< /p>,c++,fstream,signedness,C++,Fstream,Signedness,另外,请务必从我找到的“bmp文件图像读取器”库中查看此函数: bool BMPImage::readInfo() { //... //read bmp and dib headers unsigned char header[28] = {0}; _ifs->read((char*)header, 28); _width = *(int*)&header[18]; //width is located in [18] and is

另外,请务必从我找到的“bmp文件图像读取器”库中查看此函数:

bool BMPImage::readInfo()
{
    //...

    //read bmp and dib headers
    unsigned char header[28] = {0};
    _ifs->read((char*)header, 28);
    _width    = *(int*)&header[18]; //width is located in [18] and is 4 bytes size
    _height   = *(int*)&header[22]; //height is located in [22] and is 4 bytes size
    _bpp      = (unsigned char) *(short*)&header[28]; //bpp is located in [28] and is 2 bytes size
    _channels = _bpp / 8; //set num channels manually

    //...

为什么
\u ifs->read()
行仍然有效?从无符号字符到字符的强制转换会导致数据丢失,如果
char
unsigned char
具有相同的大小,则在它们之间转换时不应出现数据丢失

话虽如此,请记住,
fstreamm
只是
std::basic_fstream
对chars的专门化:

// from <fstream>
typedef basic_fstream<char>         fstream;
//来自
typedef basic_fstream;
您可以为未签名字符创建自己的类型,如下所示:

typedef basic_fstream<unsigned char> ufstream; 
typedef基本流ufstream;

被教导的是,C++中的代码<字节> /COD>等价于<代码>无符号char <代码> < /p> 我不知道什么是

byte
,但是你可以用
char
来表示一个字节

那么为什么[fstream.read和fstream.write]将字符指针作为参数呢

fstream
是std::basic_fstream的别名
std::basic\u fstream
是一个模板,其所有操作都处理其指定的
char\u类型
。由于
char\u类型
char
,因此所有操作都处理
char
,而不是
unsigned char

你可以像Juan建议的那样使用
basic\u fstream
,但它比这更复杂。您需要专门化
char\u traits
,这是
basic\u fstream
的第二个(默认)模板参数


从无符号字符到字符的转换会导致数据丢失,不是吗

否。通过
char*
访问
unsigned char
不会丢失任何数据。事实上,通过
char*
访问任何类型都不会丢失数据


另一方面:

*(int*)&header[18]

具有未定义的行为,除非缓冲区正确对齐,使得
头[18]
恰好位于
int
所需的边界。我在数组的定义中看不到这样的保证。有些体系结构根本不支持未对齐的内存访问 char < /C> >是签名还是未签名,并且实现也可以自由地实现。有两种不同的类型:
signed char
(保证至少保存范围[-127127])和
unsigned char
(保证至少保存范围[0255]),而
char
将等同于其中一种类型,但它是根据其所属的实现定义的


考虑到ASCII字符集仅包含0到127的值,从历史上看,单个有符号字节就足以容纳单个字符,同时仍然使用与较大类型相同的约定,其中整数类型默认为有符号的,除非明确声明为
无符号

“将无符号字符强制转换为字符会导致数据丢失,否?”-否。
char
unsigned char
具有相同的大小,即1字节。唯一的区别是有符号性:
unsigned char
始终大于0;正常的
char
也可以有符号(但不必有符号)。在
char
unsigned char
之间没有实际的区别。但是由于大多数人在他们的程序中使用
char
,API接受大多数使用的类型是很自然的。甚至更好的问题是:为什么它不是一个void*?这样我就可以隐式地将数据读入任何指针,而无需重新解释。是c-s吗在执行这些文件io操作时,tyle可以很好地强制转换?另外,为什么这些函数仍然使用char而不是unsigned char?或者甚至使用void*作为c等价物?