使用指针将char *转换为unsigned char *

时间:2015-02-01 00:29:17

标签: c++ pointers fstream reinterpret-cast

我正在编写一些使用fstream read()函数的代码,这个函数需要一个char *作为缓冲区。稍后,我想使用此缓冲区中的字节作为无符号字符,因此我要么必须:1。将缓冲区声明为char *,然后为每个元素执行static_casts,2。声明将缓冲区作为unsigned char *,然后在将其传递给read函数时执行reinterpret_cast,或者3.将缓冲区声明为char *,并创建一个用于访问缓冲区作为unsigned char的转换指针。

这是一个片段:

char* buf = new char[512];
unsigned char* ubuf = reinterpret_cast<unsigned char*>(buf);

    fstream myfile;

    myfile.open("foo.img");

    myfile.seekg(446);
    myfile.read(buf, 16);
    //myfile.read(reinterpret_cast<char*>(buf), 16);

int bytes_per_sector = ubuf[1] << 8 | ubuf[0];
...

我喜欢这种方式,因为我只需要施放一次,我可以只使用任何一种类型访问缓冲区,而不必每次都进行转换。但是,这是一个好习惯吗?有没有什么可以在这里出错?使用reinterpret_cast让我有点紧张,因为我通常不会使用它,并且我被告知要多次小心。

1 个答案:

答案 0 :(得分:6)

在这种情况下,reinterpret_cast很好,原因有两个:

  1. (签名)charunsigned char类型必须具有相同的"representation and alignment"。这意味着数据不会有差异(它将是每位精确位数),或者解释缓冲区的时间长度。

  2. 文件读取功能通常使用char*作为通用数据访问类型。他们无法使用void*,因为类型void具有明确未定义的长度和表示。 char,但是,确实如此。所以他们可以用它来读/写一系列字节。

  3. 实际上,文件功能通常用于将数据重新解释为其他内容。它允许你有一个像

    这样的结构
    typedef struct structSomeStruct
    {
        char name[8]; // a basic, fixed length, string
        unsigned long i; // a 32 bit value
        float x, y, z, w;
    } SomeStruct;
    

    或者

    class SomeStruct
    {
        public:
            char name[8];
            unsigned long i;
            float x, y, z, w;
    
            SomeStruct()
            {
                // ...
            }
    };
    

    使用以下内容将其存储到文件中:

    SomeStruct st;
    
    // populate the st data structure
    
    // file.write(char* start_of_data, size_t number_of_bytes);
    file.write(reinterpret_cast<char*>(&st), sizeof(SomeStruct));
    

    同样阅读。