3

据我所知,read()是否write()可以直接从文件读取字节或向文件写入字节,并且我被告知bytec++ 中的 a 等价物是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()条线仍然有效?从 unsigned char 转换为 char 强制数据丢失,不是吗?

4

3 回答 3

1

在 C 和 C++ 中,标准没有指定是char有符号还是无符号,实现可以自由地实现它。有单独的类型signed char(保证至少包含范围 [-127,127])和unsigned char(保证至少包含范围 [0,255]),并且char将等效于其中之一,但它是定义的实现.

鉴于 ASCII 字符集仅包含 0 到 127 的值,因此从历史上看,单个有符号字节已被视为足以容纳单个字符,同时仍使用与较大类型相同的约定,其中整数类型是默认签名,除非明确声明为unsigned.

于 2017-07-20T00:04:02.950 回答
0

鉴于此char并且unsigned char具有相同的大小,在它们之间进行转换时应该没有数据丢失。

话虽如此,请记住这fstreamm只是std::basic_fstreamfor chars 的一个特化:

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

您可以为 unsigned char 创建自己的类型,如下所示:

typedef basic_fstream<unsigned char> ufstream; 
于 2017-07-19T15:08:06.023 回答
0

被教导bytec++ 中 a 的等价物是unsigned char

我不知道是什么byte,但你可以用它char来表示一个字节就好了。

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

fstream是 的别名std::basic_fstream<char>std::basic_fstream是一个模板,其所有操作都处理其指定的char_type. 既然char_typechar,所有操作都处理char,不是unsigned char

你可以basic_fstream<unsigned char>按照 Juan 的建议使用,但它比这更复杂。您需要专门化 .char_traits<unsigned char>的第二个(默认)模板参数basic_fstream<unsigned char>

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

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


另一方面:

*(int*)&header[18]

具有未定义的行为,除非缓冲区已正确对齐,以至于header[18]恰好位于int. 我在数组的定义中看不到这样的保证。一些架构根本不支持未对齐的内存访问。

于 2017-07-19T23:47:27.900 回答