简体   繁体   English

从重定向的标准输入中获取输入时使用seekg()

[英]Using seekg() when taking input from redirected stdin

So i'm trying to read in a string of characters twice using cin.get(). 因此,我尝试使用cin.get()两次读取一个字符串。 The input is being redirected as "program < input". 输入被重定向为“程序<输入”。 So it is valid to use seekg(). 因此,使用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. 正如titel所说,我认为我可以使用seekg()保存字符串的起始位置,因此我可以再次使用同一字符串的起始位置。

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. 第二个while循环什么也没做,所以我显然没有正确使用seekg。 Could someone tell me what I'm doing incorrectly? 有人可以告诉我我做错了什么吗?

Thanks for any help! 谢谢你的帮助!

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 user @ host:/ tmp> ./a.out
Failed to seek 寻求失败
Failed to seek 寻求失败
user@host:/tmp > ./a.out < test.cc user @ host:/ tmp> ./a.out <test.cc
OK

You can't do that. 你不能那样做。 std::cin is usually connected to a terminal, and so random access is out of the question. std :: cin通常连接到终端,因此无法进行随机访问。

You could do that if the stream you were using was a std::istringstream or an std::ifstream. 如果您使用的流是std :: istringstream或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. 我的建议是将std :: cin中的所有字符读入一个std :: string中,然后从该字符串中创建一个std :: istringstream,然后在该std :: istringstream而不是std :: cin上尝试使用您的技术。

You cannot seek on streams. 您无法在流中搜索。 You must unget the characters. 您必须取消字符。

You can't seek on streams, but you can use either std::cin.peek() or std::cin.unget() . 您不能在流上搜索,但是可以使用std::cin.peek()std::cin.unget()

1) By using cin.peek() 1)通过使用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() 2)通过使用cin.unget()

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

cin.unget();

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM