Вопрос

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;
}
Это было полезно?

Решение

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;
}

Другие советы

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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top