从文件中读取错误的值 我对C++编码是新的。我的应用程序需要将变量写入文件,然后我想再次读取它们来做一些工作

从文件中读取错误的值 我对C++编码是新的。我的应用程序需要将变量写入文件,然后我想再次读取它们来做一些工作,c++,file-handling,C++,File Handling,我将值分配给变量,然后转储到文件中,但当我读取文件并检查变量时,它会被分配不同的值。 下面是我正在使用的3个结构 struct fence_t { uint8_t b:1; uint8_t fence_1:2; uint8_t fence_2:2; uint8_t res:3; }; struct head_t { uint8_t format; fence_t fence; }; struct pack_t { he

我将值分配给变量,然后转储到文件中,但当我读取文件并检查变量时,它会被分配不同的值。 下面是我正在使用的3个结构

struct fence_t
{
     uint8_t b:1;
     uint8_t fence_1:2; 
     uint8_t fence_2:2; 
     uint8_t res:3; 
};

struct head_t
{
    uint8_t format; 
    fence_t fence; 
};

struct pack_t
{
    head_t header;
    .
    .
    .
}
我指定了format=2

packet[i].header.format=2;
packet[i].header.fence.b=0;         
packet[i].header.fence.fence_1=2;
packet[i].header.fence.fence_2=2;
packet[i].header.fence.res=0;  
这就是我打开文件并在上面转储数据的方式。我希望值以十六进制格式写入

f = fopen("packets.txt","w");

fprintf(f, "%04X", packet[i].header);
现在在另一个函数中,我想读取文件

    ff.seekg(0,ios::end);
    size=ff.tellg();
    memblock = new pack_t [size/sizeof(pack_t)];
    ff.seekg(0,ios::beg);
    ff.read((char *)memblock,size);

    void * p = (void *)memblock;    

    for(int i=0;i<3;i++)
    {
        struct q_entry_t t = {i, p};
        queue1.push_back(t);
        p = (void *)((uintptr_t)p+64);
    }
ff.seekg(0,ios::end);
大小=ff.tellg();
memblock=新包装[尺寸/尺寸(包装)];
ff.seekg(0,ios::beg);
ff.read((char*)memblock,大小);
void*p=(void*)memblock;

对于(int i=0;i有几个问题:

  • 您通过
    fprintf()
    中的值传递
    packet[i]。头
    ,并告诉
    fptrintf()
    这是一个
    int
    ,它的值应以ascii十六进制格式写入。编译器可能会以
    int
    的大小传递值,您将得到一个可用的值。但编译器传递的数据也可能比int多或少(因为您的头是一个结构,可能需要进行对齐填充),然后,您将编写的值将不是您期望的值。因此,它非常依赖于实现

  • 顺便说一下,即使您的编译器传递了一个适当大小的值,由于endianness,您也可能有不可移植的文件

  • 然后,将数据当作二进制文件来读取(不以“rb”形式打开文件会造成严重破坏)。因此,您将只读取部分ascii数据,并以完全不同的方式解释编码(即,您写入“1”,但读取0x31)。这两种方式都不起作用。您必须使用
    fscanf()读取它
    ,与您编写的逻辑相同。但如上所述,这非常依赖于实现

作为简单的替代方案,我建议您使用
ios::binary
以二进制fstream的形式打开文件,并使用/来编写内存块,使用数据元素的地址及其确切大小


作为一种更便于携带的替代方案,您可以使用文本文件流,并对类型
头\u t
重载
,以使用受控(即固定字节顺序)的十六进制格式。

通常,如果您使用fprintf编写,然后使用fscanf或getline;即面向行/ASCII的输入机制进行读取

如果您希望文件是结构化的二进制文件,那么使用write写入,使用read读取


不要将这两种机制混在一起

似乎您正在以ASCII格式编写,并试图以二进制格式读回。您想做什么?为了清楚起见,您的工具链在执行此操作时没有发出警告:
fprintf(f,“%04X”,packet[i]。header)
?也就是说,将
头\u t
发送到
printf
-需要无符号整数的族说明符?很有趣。转到C/C++项目属性并提高警告级别。应该检测到这一点。最好使用
fwrite
,它不需要任何形式的格式化输入。您可以如果你熟悉C++的方式来做这件事(即使有一点困难),而不是旧的C方式,那就更好了。
cout<<((head_t *)p)->format<<endl;