据我所知,read()
和write()
都在那里,所以我们可以直接从文件读取和写入字节,而且我被告知 c++ 中相当于byte
是unsigned char
,那么为什么它们将指针作为参数char
呢?
另外,请从我找到的"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
//...
为什么_ifs->read()
线仍然有效?从未签名字符到字符的转换会强制丢失数据,不是吗?
在 C 和 C++ 中,标准没有指定char
是有符号还是无符号,并且实现可以自由地实现它。有单独的类型signed char
(保证至少保持范围 [-127,127](和unsigned char
(保证至少保持范围 [0,255](,char
将等同于其中之一,但它是实现定义的。
鉴于 ASCII 字符集仅包含值 0 到 127,因此从历史上看,单个有符号字节被视为足以保存单个字符,同时仍使用与较大类型相同的约定是有道理的,其中整数类型默认签名,除非显式声明为unsigned
。
鉴于char
和unsigned char
具有相同的大小,在它们之间转换时应该不会丢失数据。
话虽如此,请记住,fstreamm
只是字符std::basic_fstream
的专业化:
// from <fstream>
typedef basic_fstream<char> fstream;
您可以为无符号字符创建自己的类型,如下所示:
typedef basic_fstream<unsigned char> ufstream;
被教导说,在C++中相当于
byte
是unsigned char
我不知道byte
是什么,但你可以用char
来表示一个字节就好了。
那么为什么 [fstream.read 和 fstream.write] 将 char 指针作为参数呢?
fstream
是std::basic_fstream<char>
的别名。std::basic_fstream
是一个模板,其所有操作都处理其指定的char_type
。由于该char_type
是char
,所有操作都处理char
,而不是unsigned char
。
你可以按照胡安的建议使用basic_fstream<unsigned char>
,但它比这更复杂。您将需要专门化char_traits<unsigned char>
这是basic_fstream<unsigned char>
的第二个(默认(模板参数。
从未签名字符到字符的转换会强制丢失数据,不是吗?
不。通过char*
访问unsigned char
不会丢失任何数据。实际上,通过char*
访问任何类型的都不会丢失数据。
另一方面,这:
*(int*)&header[18]
具有未定义的行为,除非缓冲区正确对齐,使得header[18]
缓冲区恰好位于int
所需的边界处。我在数组的定义中看不到这样的保证。某些体系结构根本不支持未对齐的内存访问。