C++ 二进制文件 I/O,写入时数据丢失

C++ binary files I/O, data lost when writing

我正在通过 Bjarne Stroustrup 的“编程:使用 C++ 的原理和实践”一书学习 C++。我目前正在学习第 11 章,我找到了一个关于如何 读取和写入整数的二进制文件 的示例(第 11.3.2 节)。我尝试了这个例子,并使用了一个 .txt 文件 (input.txt) 和一个句子,我读取并写入另一个文件 (output.txt) (text_to_binary fnc) 然后读取和写入回到原始文件 (input.txt) (binary_to_text fnc).

#include<fstream>
#include<iostream>

using namespace std;

void text_to_binary(ifstream &ifs, ofstream &ofs)
{
    for (int x; ifs.read(as_bytes(x), sizeof(char));)
    {
        ofs << x << '\n';
    }
    ofs.close();
    ifs.close();
}

void binary_to_text(ifstream &ifs, ofstream &ofs)
{
    for (int x; ifs >> x;)
    {
        ofs.write(as_bytes(x), sizeof(char));
    }
    ifs.close();
    ofs.close();
}

int main()
{
    string iname = "./chapter_11/input.txt";
    string oname = "./chapter_11/output.txt";

    ifstream ifs{iname, ios_base::binary};
    ofstream ofs{oname, ios_base::binary};

    text_to_binary(ifs, ofs);

    ifstream ifs2{oname, ios_base::binary};
    ofstream ofs2{iname, ios_base::binary};

    binary_to_text(ifs2, ofs2);

    return 0;
}

我发现我必须在 .read 和 .write 中使用 sizeof(char) 而不是 sizeof(int)命令。如果我使用 sizeof(int),当我将它们写回文本时,.txt 文件的某些字符会丢失。有趣的是,只有在

时才会丢失足够多的字符

x%4 != 0 (x = nb of chars in .txt file)

带有 sizeof(int) 的示例:

input.txt: hello this is an amazing test. 1234 is a number everything else doesn't matter..asd

(text_to_binary fnc) 结果:

output.txt:

1819043176
1752440943
1763734377
1851859059
1634558240
1735289210
1936028704
824192628
540291890
1629516649
1836412448
544367970
1919252069
1768453241
1696622446
543519596
1936027492
544483182
1953784173
774795877

(binary_to_text fnc) 结果返回:

input.txt: hello this is an amazing test. 1234 is a number everything else doesn't matter.. asd 失踪了。

现在回答我的问题,为什么会发生这种情况?是因为int的存为4字节吗?

奖金问题:出于兴趣,是否有 simpler/more 有效的方法来做到这一点?

编辑:用结果更新了问题,希望更清楚

当您尝试进行部分读取时,读取将尝试超出文件末尾,并且将为流设置 eof 标志。这使得它在循环条件 false 中使用,因此循环结束。

您需要在 循环后检查流 gcount 以查看是否有任何字节实际读入变量 x.

但是请注意,部分读取只会写入变量的一部分x,剩下的不确定。具体哪些部分取决于系统 endianness,并且使用具有不确定位的变量将导致 未定义的行为