如何在C++中从cin读取EOF

Gui*_*lle 75 c++ iostream input

我正在编写一个程序,直接从用户输入读取数据,并想知道我怎么能(没有循环)读取所有数据,直到标准输入EOF.我正在考虑使用,cin.get( input, '\0' )'\0'不是真正的EOF角色,只读到EOF或者'\0'以先到者为准.

或者使用循环是唯一的方法吗?如果是这样,最好的方法是什么?

小智 66

从stdin读取可变数据量的唯一方法是使用循环.我总是发现这个std::getline()功能非常好用:

std::string line;
while (std::getline(std::cin, line))
{
    std::cout << line << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,getline()会读取直到换行符.您可以指定另一个终止字符,但EOF本身不是一个字符,因此您不能简单地调用getline().

  • 这里需要注意的是当你从通过标准输入管道传输的文件中读取时,这个以及给出的大部分答案都会在输入结尾附加一个额外的换行符.并非所有文件都以换行符结尾,但循环的每次迭代都会将"std :: endl"附加到流中.在大多数情况下,这可能不是问题,但如果文件完整性是一个问题,这可能会回来咬你. (6认同)
  • 这不应该是得票最多的答案。请参阅下面的社区 wiki 答案。另外,也许会看到这个问题:/sf/ask/224241671/ (3认同)

Kei*_*thB 47

您可以使用流迭代器在没有显式循环的情况下执行此操作.我确信它在内部使用某种循环.

#include <string>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>

int main()
{
// don't skip the whitespace while reading
  std::cin >> std::noskipws;

// use stream iterators to copy the stream to a string
  std::istream_iterator<char> it(std::cin);
  std::istream_iterator<char> end;
  std::string results(it, end);

  std::cout << results;
}
Run Code Online (Sandbox Code Playgroud)

  • 尼斯.至于"我确信它在内部使用某种循环" - 任何解决方案都会. (2认同)

Deg*_*vik 43

使用循环:

#include <iostream>
using namespace std;
...
// numbers
int n;
while (cin >> n)
{
   ...
}
// lines
string line;
while (getline(cin, line))
{
   ...
}
// characters
char c;
while (cin.get(c))
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

资源


Ric*_*ith 22

在研究了KeithB的解决方案后std::istream_iterator,我发现了std:istreambuf_iterator.

测试程序将所有管道输入读入字符串,然后再将其写出:

#include <iostream>
#include <iterator>
#include <string>

int main()
{
  std::istreambuf_iterator<char> begin(std::cin), end;
  std::string s(begin, end);
  std::cout << s;
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是规范的答案. (3认同)
  • Downvoted.那么与KeithB的解决方案相比,有什么优缺点?是的,你使用的是`std :: istreambuf_iterator`而不是`std :: istream_iterator`,但是对于什么? (2认同)
  • std::istreambuf_iterator 默认情况下会跳过空格并且速度更快 (2认同)

Fra*_*kHB 5

可能最简单,效率最高:

#include <iostream>
int main()
{
    std::cout << std::cin.rdbuf();
}
Run Code Online (Sandbox Code Playgroud)

如果需要,请std::ostringstream在此处使用其他类型的流,如缓冲区而不是标准输出流.


luk*_*uke 2

您可以使用std::istream::getline()(或者最好是适用于 std::string 的版本)函数来获取整行。两者都有允许您指定分隔符(行尾字符)的版本。字符串版本的默认值为“\n”。