由于eof在C ++中读取了两次文件? [英] Read a file twice in C++ because of eof?

查看:95
本文介绍了由于eof在C ++中读取了两次文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从文件中读取数字,应用3个函数并打印到另一个文件:

I read numbers from a file, apply 3 functions and print out to another file:

int main(int argc, char** argv) {
    std::ifstream fin;
    fin.open("input.txt");

    std::ofstream fout;
    fout.open("output.txt", std::ios::app);

    char arr[50];
    int a,b;
    int N;//number to factor

    while (!fin.eof()){
        //Print backward
        fin >> arr;
        PrintBackward( arr );
        fout << endl;

        //Greatest common divisor
        ((fin >> a) >> b);
        fout << gcd( a, b );
        fout << endl;

        //Find prime factor
        fin >> N;
        PrimeFactor(N);
        fout << endl;     
    }

    fin.close();
    fout.close();

    return 0;
}

运行后,结果重复:

olleh
3
2 3 7 
olleh
3
2 3 7

我读过一篇类似的文章,但它涉及到读入1个变量,因此似乎不可行。

I read a similar article but it's about reading into 1 variable so it seems not to be feasible.

如果我在 while 循环的结尾设置了中断精细。有什么方法不使用 break

If I set a break at the end of the while loop, it's fine. Is there any way not to use break?

推荐答案

while(!whatever.eof())本质上总是错误的,并且永远不会正确检测文件的结尾。在您的情况下,最简单的方法是将读取合并在一起,然后进行所有处理,如下所示:

while (!whatever.eof()) is essentially always wrong, and will never detect the end of the file correctly. In your case, it's easiest to coalesce the reads together, and then do all the processing, something like this:

while (fin >> arr >> a >> b >> N) {
    PrintBackwards(arr);
    fout << "\n";

    fout << gcd(a, b) << "\n";

    fout << PrimeFactor(N) << "\n";
}

关键部分是检查读取结果,而不是检查和

The crucial part is to check the result of the read, instead of checking and reading separately from each other.

另外一些建议:我会使用 std :: string 而不是数组。我还将反转字符串与打印字符串分开,所以您可以使用类似的东西:

A couple more bits of advice: I'd use an std::string instead of an array. I'd also separate reversing the string from printing it, so you can have something like:

fout << reverse(arr)   << "\n" 
     << gcd(a, b)      << "\n" 
     << PrimeFactor(N) << "\n";

增强操作之间的共性往往是一件好事。

Emphasizing the commonality between the operations tends to be a good thing.

编辑:只是为了好玩,我会指出另一种您可以根据需要进行操作的方式。由于您基本上是作为一个组来阅读和处理这四个项目,因此可以使该分组更为明确:

Just for fun, I'll point out another way you could do things if you wanted. Since you're basically reading and processing the four items as a group, you could make that grouping a bit more explicit:

struct item { 
     std::string arr;
     int a, b, N;

     friend std::istream &operator>>(std::istream &is, item &i) { 
         return is >> arr >> a >> b >> N;
     }
};

struct process {
    std::string operator()(item const &i) { 
        std::ostringstream buffer;

        buffer << reverse(arr) << "\n" << gcd(a, b) << "\n" << PrimeFactor(N);
        return buffer.str();
    }
}

这样,您可以让标准库处理所有读取和写入,检查文件结尾等详细信息:

With this, you can let the standard library deal with all the details of the reading and writing, checking end of file, etc.:

std::transform(std::istream_iterator<item>(fin), 
               std::istream_iterator<item>(),
               std::ostream_iterator<std::string>(std::cout, "\n"),
               process());

这篇关于由于eof在C ++中读取了两次文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆