为什么fstream.read和fstream.write使用字符而不是无符号字符? 我知道,代码> >()和代码>和代码>(或)代码>我们可以直接从文件中读取文件,并在文件中写入字节,并且我被教导在C++中等价于字节是代码>未签名char < />代码,为什么他们使用 char < /Case>指针作为参数?< /p>
另外,请务必从我找到的“bmp文件图像读取器”库中查看此函数:为什么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
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
所需的边界。我在数组的定义中看不到这样的保证。有些体系结构根本不支持未对齐的内存访问在C和C++中,标准没有指定“代码> 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等价物?