Pregunta

I have something as below in c++.

I want to read a file for several times, but failed.

Though I use fseek to move to the head of the file after I freopen again, but I still can only read it once. For the second time, cin get nothing @.@.

I'm really confused with it.

(It seems c's freopen can work, but I really want to use cin ...)

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;

int main(){
    for (int i=0; i<2; i++) {
        freopen("windmill02.mtl", "r", stdin);
        fseek(stdin, 0, 0);
        string s0, name, filename;
        while (cin>>s0) {
            cin>>name;
            cin>>filename;
            cout <<name<<" "<<filename<<endl;
        }
        freopen("ke.txt","r",stdin);
    }   
    return 0;
}
¿Fue útil?

Solución

Mixing C and C++ to read a file is not really recommended. It works at the beginning but it seems by seeking on stdin, it gets de-synchronized with cin which is always at the end of file. Since you did everything in C, here's a version that work using scanf instead:

int main(){
    char s0[256];
    char name[256];
    char filename[256];

    freopen("windmill02.mtl", "r", stdin);

    for (int i=0; i<2; i++) {
        fseek(stdin, 0, 0);

        while (!feof(stdin)) {
            scanf("%s", s0);
            scanf("%s", name);
            scanf("%s", filename);

            cout << name << " " << filename << endl;
        }
    }

    fclose(stdin);
    return 0;
}

Otros consejos

why frepoen stdin?

you should not use such way to mix Cio and C++io.

if you need to read external file, use fstream. freopen stdio does not bring benefits here.

And, stdin is never supposed to work with fseek. fseek works on a physically existing file, but stdin/stdout is actually a virtual file usually associated with a pipe or console device, which are sequential and can't seek to another position. How fseek responds depends on file stream attributes, which is platform dependent, and may not be changed by freopen.

I tested your code, it works fine on my system.

c++ approach

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    const char *filenames[] = {"windmill02.mtl", "ke.txt"};
    std::string s0, name, fname;    

    for (const char **fptr = &filenames[0]; fptr != &filenames[2]; ++fptr)
    {
        std::fstream fin (*fptr, std::ios_base::in);
        while(fin >> s0 >> name >> fname)
            std::cout << name << " " << fname << std::endl;
        fin.close();
    }

    return 0;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top