繁体   English   中英

浏览文本文件 c++

[英]Moving through text file c++

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

然后,另一个错误是,在第二个 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;
}

编辑output 是:

长度 = 7 1. a = 0 2. a = 0 3. a = 0 4. a = 0 5. a = 0 6. a = 0 7. a = 0 ------------ -------------------- 进程在 0.03841 秒后退出,返回值为 0 按任意键继续。 . .

问题

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

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

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

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 非常缓慢。 你不想做两次。 您想读取文件一次并存储为 go 而不关心文件中有多少数字。

幸运的是,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 << ' ';
}

std::reverse的文档

如果您的讲师没有vector政策,不幸的是很多人这样做,您最好的选择是编写您自己的简单版本的vector Stack Overflow 上已经有很多关于如何做到这一点的例子。

附录

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

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

但事实并非如此。 不同的计算机和不同的编译器对整数使用不同的大小 你所保证的是一个int至少是 2 个字节并且不大于一个long 所有 integer 类型在 64 位时的大小可能完全相同。 废话。 更糟糕的是,并非所有计算机都以相同的顺序存储整数。 因为如果数字向后存储更容易进行一些操作,你猜怎么着? 通常,数字是向后存储的。 您必须非常非常小心地处理二进制数据并建立一个数据协议(搜索有关此主题的更多信息:序列化),该协议定义了每个人如何解释数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM