为什么 fstream.read 和 fstream.write 使用 char 而不是无符号字符?
Why do fstream.read and fstream.write use char and not unsigned char?
据我所知,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
所需的边界处。我在数组的定义中看不到这样的保证。某些体系结构根本不支持未对齐的内存访问。
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- C++中无符号字符溢出
- 使用无符号字符数组有效存储内存
- 如何打印boost多精度128位无符号整数
- C++模板函数,用于比较任何无符号整数和有符号整数
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 获取隐式转换溢出从无符号到已签名的警告
- 如何在保持其值的同时将 c++ 无符号字符变量转换为 char 变量
- 从 std::vector<无符号字符>切片中提取 int?
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- 将无符号字符的向量存储在数组中会给我 std::bad_alloc
- 使用 fopen 打开 .pak 文件并使该文件应用于 const 无符号字符* (C++)
- C4018:类内有符号、无符号不匹配
- C++无符号短裤的划分导致 int
- 为什么 fstream.read 和 fstream.write 使用 char 而不是无符号字符?