gpt4 book ai didi

c++ - 在文本文件中移动 C++

转载 作者:行者123 更新时间:2023-11-28 04:04:46 24 4
gpt4 key购买 nike

我正在尝试以相反的顺序将数字从第一个 txt 文件保存到第二个文件。需要明确的是,在 1st txt 中,我输入了从 1 到 10 的数字(十进制)。当我尝试对它们进行计数时,我得到 5 或 7,具体取决于它们之间的内容(空格或回车)。

然后,另一个错误是在第 2 个 txt 程序中保存了与 dl 的变量值相等的“0”,而不是按相反顺序加载的数字。

我粘贴了整个代码,因为我不知道文件操作规则是否足够好来确定哪个部分可能是问题的根源。提前谢谢你。

#include <fstream>
#include <iostream>

using namespace std;

int main() {
fstream plik1;
plik1.open("L8_F3_Z2a.txt", ios::in | ios::binary);
fstream plik2;
plik2.open("L8_F3_Z2b.txt", ios::out);

if(!plik1.good() || !plik2.good()) {
cout << "file(s) invalid" << endl;
return 1;
}

plik1.seekg(0, ios::end);
int dl = plik1.tellg() / sizeof(int);

cout << "length = " << dl << endl;

int a;
for(int i = 0; i < dl; i++) {
plik1.seekg((i + 1) * sizeof(int), ios::end);
plik1 >> a;
plik2 << a;
cout << i + 1 << ". a = " << a << endl;
}
plik1.close();
plik2.close();
return 0;
}

编辑输出为:

length = 71. a = 02. a = 03. a = 04. a = 05. a = 06. a = 07. a = 0--------------------------------Process exited after 0.03841 seconds with return value 0Press any key to continue . . .

最佳答案

问题

当文件被编码为文本时,数据的二进制大小无关紧要。

int dl = plik1.tellg() / sizeof(int);

将以整数形式为您提供文件的一侧,但该文件不存储整数。它正在存储字符流。例如,文件包含一个数字:

12345

长度为五个字符。假设文件使用良好的 ol ASCII,即 5 个字节。当 12345 转换为 int 时,它可能是 4 或 8 个字节,几乎可以肯定不是 5 个字节。假设常见的32位(4字节)int

int dl = plik1.tellg() / sizeof(int);
int dl = 5 / 4;
int dl = 1;

耶!有效!但只有通过你崇拜的任何神灵或宇宙实体的恩典。要么不拜。我不会去评判。为了说明为什么不能指望这一点,让我们看看

123

这是三个字符和3个字节,所以

int dl = plik1.tellg() / sizeof(int);
int dl = 3 / 4;
int dl = 0;

糟糕。

同理

1 2 3 4 5

是五个数字。文件长度可能是每个数字一个字节和每个空格一个字节的总和,9 个字节。

这变得奇怪的是一些系统,看看你的 Windows,使用两个字符的行尾标记、回车和换行。这意味着

1 
2
3
4
5

将总计为 13 个字节。

这就是为什么您会看到不同大小的原因,具体取决于数字是用空格还是换行符分隔。

解决方案

找出文件中有多少个数字的唯一方法是读取文件,将内容转换为数字,并在找到数字时对数字进行计数。

怎么做:

int num;
int count = 0;
while (plik1 >> num) // read numbers until we can't read any more
{
count++;
}

由此您可以确定所需数组的大小。然后你倒回文件,回到开头,分配数组并将文件再次读入数组。这是愚蠢的。文件 IO 非常慢。你不想做两次。您希望只读取文件一次并随时存储,而不关心文件中有多少数字。

幸运的是,C++ 中内置了很多工具,它们正是这样做的。我喜欢std::vector

std::vector<int> nums;
int num;
while (plik1 >> num)
{
nums.push_back(num);
}

vector 甚至可以为您计数。

接下来你可以

std::reverse(nums.begin(), nums.end());

并将结果写回。

for (int num: nums)
{
plik2 << num << ' ';
}

Documentation for std::reverse

如果您的讲师没有vector 政策,并且unfortunately很多人都这样做,最好的办法是编写自己的 vector 简单版本。 Stack Overflow 上已经有很多关于如何执行此操作的示例。

附录

在二进制中,5 个整数可能是 20 或 40 个字节,无论使用多少位并且不需要分隔符。

这听起来就像蜜蜂膝盖一样将数据存储为二进制,对吧?好像它会变得容易得多。

但事实并非如此。不同的计算机和不同的编译器使用 different sizes for integers .您所保证的是 int 至少为 2 个字节并且不大于 long。所有整数类型在 64 位时可以具有完全相同的大小。废话。更糟的是,not all computers store integers in the same order.因为如果数字向后存储,做一些操作会更容易,你猜怎么着?通常数字是倒着存储的。您必须非常非常小心地处理二进制数据,并建立一个数据协议(protocol)(有关此主题的更多信息的搜索词:序列化)来定义每个人如何解释数据。

关于c++ - 在文本文件中移动 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58940988/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com