为什么fstream.read和fstream.write使用char而不是unsigned char?

问题描述:

据我所知,read()write()有那么我们可以读取和直接或文件写入字节,而我被教导一个byte C++中的等价物是unsigned char,那么为什么他们采取char指针作为参数?为什么fstream.read和fstream.write使用char而不是unsigned 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()线的工作呢?从unsigned char转换为char会强制丢失数据,不是吗?

+3

“从unsigned char转换为char会强制丢失数据,不是吗?” - 没有。 –

+0

'char'和'unsigned char'具有相同的大小,即1个字节。唯一的区别是签名:'unsigned char'总是> 0;正常的'char'也可以被签名(但不一定是)。 –

+0

'char'和'unsigned char'没有实际区别。但是由于大多数人在他们的程序中使用'char',所以API接受最常用的类型是很自然的。 – SergeyA

由于charunsigned char具有相同的大小,因此在它们之间转换时不应该有数据丢失。

说,必须记住,fstreamm只是一个用于字符的std::basic_fstream专业化:

// from <fstream> 
typedef basic_fstream<char>   fstream; 

您可以创建自己的类型为无符号的字符,像这样:

typedef basic_fstream<unsigned char> ufstream; 
+0

执行这些文件io操作时,c样式转换是否正常?另外,为什么这些函数仍然使用char而不是unsigned char?甚至无效*作为c等价物? – Pilpel

被教导在C++中相当于byteunsigned char

我不知道byte是什么,但是可以用char来代表字节就好了。

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

fstreamstd::basic_fstream<char>的别名。 std::basic_fstream是一个模板,其所有操作均处理其指定的char_type。由于char_typechar,所有操作都处理char,而不是unsigned char

按照Juan的说法,您可以使用basic_fstream<unsigned char>,但比这更多地涉及。您将需要专门char_traits<unsigned char>这是第二个(默认)模板参数basic_fstream<unsigned char>

从unsigned char到char的强制转换会强制丢失数据,不是吗?

编号访问unsigned char通过char*失去了没有数据。事实上,通过char*访问任何类型都不会丢失数据。


这在另一方面:

*(int*)&header[18] 

有未定义的行为,除非缓冲液适当地对准,使得header[18]恰好位于在由int所需的边界。我在数组的定义中看不到这样的保证。一些体系结构根本不支持未对齐的内存访问。

在C和C++中,标准没有指定char是有符号还是无符号,并且实现可以*实现它。有分开的类型signed char(保证至少保持范围[-127,127])和unsigned char(保证至少保持范围[0,255]),并且char将等同于它们中的一个,但是它的实现定义为它是。

由于ASCII字符集只包含值0到127,所以从历史上看,单个有符号字节将被视为足以容纳单个字符,而仍然使用与较大类型相同的约定,除非明确声明为unsigned,否则默认情况下会对整型进行标记。