0

编辑:显然,问题出在读取功能中:我在十六进制编辑器中检查了数据

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

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

因为当我使用我的正常存储在 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 正在读取最后一个值两次。

4

4 回答 4

2

int num = 0;
write( fd, &num, sizeof( int ));
于 2009-05-27T00:29:01.880 回答
1

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

PS我也猜想问题可能出在您的阅读代码中。您是否在十六进制编辑器中查看了您的 .bin 文件?

PPS您的问题在于 seekg() 函数的使用。不是以字节为单位传递偏移量,而是传递 pos。它应该是 pos * sizeof(int) 。

于 2009-05-27T00:28:17.730 回答
1

我不确定你想做什么,对我来说,你提供的代码似乎满足了你的要求:

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
于 2009-05-27T00:34:57.110 回答
0

您需要考虑二进制文件应该包含什么格式 - 您不必以与文本文件相同的方式来做这件事,这就是为什么多次使用文本文件的原因。

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

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

于 2009-05-27T00:33:49.453 回答