Using seekg() when taking input from redirected stdin

你离开我真会死。 提交于 2019-12-17 21:16:37

问题


So i'm trying to read in a string of characters twice using cin.get(). The input is being redirected as "program < input". So it is valid to use seekg().

As the titel says, I thought I would be able to use seekg() to save the beginning position of the string, so I could come back to use the starting position of the same string again.

Here is my attempt:

char c;
while (cin.get(c))
{
  //do stuff 
}

cin.seekg(0, ios::beg);

while (cin.get(c))
{
  //do stuff with the string a second time
}

The second while loop isn't doing anything, so I'm obviously not using seekg correctly. Could someone tell me what I'm doing incorrectly?

Thanks for any help!


回答1:


You can't seek on streams/pipes. They don't continue to exist in memory. Imagine the keyboard is directly connected to your program. The only operation you can do with a keyboard is ask for more input. It has no history.

If it's just a keyboard you can't seek, but if it's redirected with < in the shell seeking works fine:

#include <iostream>

int main() {
  std::cin.seekg(1, std::ios::beg);
  if (std::cin.fail()) 
    std::cout << "Failed to seek\n";
  std::cin.seekg(0, std::ios::beg);
  if (std::cin.fail()) 
    std::cout << "Failed to seek\n";

  if (!std::cin.fail()) 
    std::cout << "OK\n";
}

Gave:

user@host:/tmp > ./a.out
Failed to seek
Failed to seek
user@host:/tmp > ./a.out < test.cc
OK




回答2:


You can't do that. std::cin is usually connected to a terminal, and so random access is out of the question.

You could do that if the stream you were using was a std::istringstream or an std::ifstream.

My advice is to read all the characters from std::cin into a single std::string, then create a std::istringstream from that string, and then try your techniques on that std::istringstream instead of std::cin.




回答3:


You cannot seek on streams. You must unget the characters.




回答4:


You can't seek on streams, but you can use either std::cin.peek() or std::cin.unget().

1) By using cin.peek()

char c;
while (c = cin.peek())
{
  //do stuff 
}

while (cin.get(c))
{
  //do stuff with the string a second time
}

2) By using cin.unget()

char c;
while (cin.get(c))
{
  //do stuff 
}

cin.unget();

while (cin.get(c))
{
  //do stuff with the string a second time
}


来源:https://stackoverflow.com/questions/11765718/using-seekg-when-taking-input-from-redirected-stdin

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!