cat filename | command and command < filename behaving differently

时间:2018-02-26 17:41:38

标签: c++ inputstream stdin

    #include <string>
    #include <iostream>

    int main() {
        std::string str;
        char magic[9];
        std::cin.read((char *)magic, sizeof(magic));

        std::cout << "eof/fail=" << std::cin.eof() << '/' << std::cin.fail() << '\n';
        std::cin.clear();
        std::cin.seekg(0, std::ios::beg);
        std::cout << "eof/fail=" << std::cin.eof() << '/' << std::cin.fail() << '\n';

        while (std::cin >> str) {
            std::cout << str << std::endl;
        }
    }

my code contains implementation of seekg(0) fucntion on std::cin

it is behaving differently when run as ./a.out < filename and cat filename | ./a.out

I was considering both the ways equivalent . but I am surprised to see that they behave differently

my question is What is the main difference in both ways ? Aren't they both a way to get standard input ?

1 个答案:

答案 0 :(得分:1)

Aren't they both a way to get standard input ?

Yes, but…

I was considering both the ways equivalent .

They are very much not equivalent.

cat filename | ./a.out

Here, your shell runs the program cat, telling it to echo the contents of a file called filename. It also runs the program a.out. It opens up a "pipe" between them and streams information from one's standard output stream, to the other's standard input stream.

./a.out < filename

Here, your shell runs the program a.out, making the file filename available via the process's standard input stream. This is called input redirection.


You can seek around a "file" (more generally, block device). In the case of input redirection from a file, your shell cleverly tells your program that it can treat the stream as a block device, so you can enjoy seekness.

But, with a pipe, once you've consumed your data, that's it it's gone. You can't go back to the beginning; it's not a container. It's a flow of data.