编辑:显然,问题出在 read 函数上:我在十六进制编辑器中检查了数据

02 00 00 00 01 00 00 00 00 00 00 00

所以零被存储为零,只是不读取为零。

因为当我使用正常的 store-in-bin 文件功能时:

int a = 0;
file.write(reinterpret_cast<char*>(&a), sizeof(a));

它将 0 存储为 char 版本,或“\0”,显然没有存储(因为它是一个空值?),所以当我调用我的函数来读取零值时,它会读取它后面的值(或者如果它是文件最后)。那么如何在 .bin 文件中正确存储零呢?

编辑:以下是一些与读/写过程相关的函数:

//Init program: creates a sector.bin for another program to read from.
#include<fstream>
using namespace std;

int main()
{
    fstream file;
    file.open("sector.bin", ios::out | ios::binary);
    if(!file.is_open())
    {
        file.open("sector.bin", ios::out | ios::binary);
        file.close();
        file.open("sector.bin", ios::out | ios::binary);
        if(!file.is_open())
        {
            return -1;
        }
    }
    file.seekp(file.beg);
    int a = 2;
    int b = 1;
    int c = 0;
    file.write(reinterpret_cast<char*>(&a), sizeof(a));
    file.write(reinterpret_cast<char*>(&b), sizeof(b));
    file.write(reinterpret_cast<char*>(&c), sizeof(c));
    file.close();
    return 0;
}

//Read function:  part of another program that intializes variables based off
//of sector.bin
void sector::Init(std::fstream& file)
{
    int top_i = FileRead(file,0);
    std::cout<<top_i<<std::endl;
    for(int i = 0; i < top_i; i++)
    {
        accessLV[i] = FileRead(file,i+1);
        std::cout<<accessLV[i]<<std::endl;
    }
    std::cin.ignore();
    viral_data.add(new X1(5,5,'X'));
    viral_data.add(new X1(9,9,'X'));
    player.set(0,0,'O');
    return;
}
//the FileRead used in init
int FileRead(std::fstream& file, int pos)
{
    int data;
    file.seekg(file.beg + pos);
    file.read(reinterpret_cast<char*>(&data), sizeof(data));
    return data;
}

另外,使用的输出 sector::Init 如下:

2
1
1

我试图写入垃圾箱的输出是

2
1
0

因此,要么 0 被读/写为 1,要么它没有被写入并且 Init 读取最后一个值两次。

有帮助吗?

解决方案

目前还不清楚你所说的在一个文件中“存储整数值0”的意思。文件包含字节,而不是整数。你需要存储的sizeof(int)的0字节,或者只是一个 '\ 0' 字节?

P.S。我也想这个问题可能是在你读代码。你看看你的.bin文件中的十六进制编辑器?

P.P.S。 您的问题是在seekg()函数的使用。取而代之的传递字节偏移量,你通过POS机。它应该是正的sizeof *(int)的代替。

其他提示


int num = 0;
write( fd, &num, sizeof( int ));

我不知道你想做什么,对我来说,好像你所提供的代码做你问什么:

int main() {
   std::ofstream file("/tmp/tst.out");
   int a = 0;
   file.write(reinterpret_cast<char*>(&a), sizeof(a));
   return 0;
}

这导致在包含零的整数的二进制表示的四个字节大小的文件:

$ hexdump /tmp/tst.out
0000000 0000 0000
0000004

如果你想存储整数,因为它是ASCII码表示你应该使用<<格式的流输出:

std::ofstream file("/tmp/tst.out");
int a = 0;
file << a << std::endl;

这样,您可以:

$ cat /tmp/tst.out
0

您需要考虑二进制文件应包含什么格式 - 您不必以与文本文件相同的方式执行此操作,这就是多次使用文本文件的原因。

假设一台(32位)机器,其中 sizeof(int) == 4 (并且 CHAR_BITS == 8),那么您可以使用本机格式在当前文件位置存储全为零的 4 个字节,那么您将得到什么我认为应该有效。您可以尝试其他值,例如 0x01020304,您将看到计算机上的字节布局。

当然,您需要小心地将其读回,并反转用于写入的过程。并且在尝试重新读取刚刚写入的数据之前,不要忘记重新定位文件。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top