#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 ?
答案 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.