C++ 如何从C ++中的cin读取直到EOF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/201992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:40:38  来源:igfitidea点击:

How to read until EOF from cin in C++

c++inputiostream

提问by Guille

I am coding a program that reads data directly from user input and was wondering how could I (without loops) read all data until EOF from standard input. I was considering using cin.get( input, '\0' )but '\0'is not really the EOF character, that just reads until EOF or '\0', whichever comes first.

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

Or is using loops the only way to do it? If so, what is the best way?

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

回答by trotterdylan

The only way you can read a variable amount of data from stdin is using loops. I've always found that the std::getline()function works very well:

从标准输入读取可变数量数据的唯一方法是使用循环。我一直发现这个std::getline()功能很好用:

std::string line;
while (std::getline(std::cin, line))
{
    std::cout << line << std::endl;
}

By default getline() reads until a newline. You can specify an alternative termination character, but EOF is not itself a character so you cannot simply make one call to getline().

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

回答by KeithB

You can do it without explicit loops by using stream iterators. I'm sure that it uses some kind of loop internally.

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

#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;
}

回答by Degvik

Using loops:

使用循环:

#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))
{
   ...
}

resource

资源

回答by Richard Smith

After researching KeithB's solution using std::istream_iterator, I discovered the std:istreambuf_iterator.

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

Test program to read all piped input into a string, then write it out again:

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

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

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

回答by FrankHB

Probable simplest and generally efficient:

可能最简单且通常有效:

#include <iostream>
int main()
{
    std::cout << std::cin.rdbuf();
}

If needed, use stream of other types like std::ostringstreamas buffer instead of standard output stream here.

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

回答by luke

You can use the std::istream::getline()(or preferably the version that works on std::string) function to get an entire line. Both have versions that allow you to specify the delimiter (end of line character). The default for the string version is '\n'.

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

回答by liborm

Sad side note: I decided to use C++ IO to be consistent with boost based code. From answers to this question I chose while (std::getline(std::cin, line)). Using g++ version 4.5.3 (-O3) in cygwin (mintty) i got 2 MB/s throughput. Microsoft Visual C++ 2010 (/O2) made it 40 MB/s for the same code.

悲伤的旁注:我决定使用 C++ IO 来与基于 boost 的代码保持一致。从这个问题的答案中,我选择了while (std::getline(std::cin, line)). 在 cygwin (mintty) 中使用 g++ 版本 4.5.3 (-O3) 我获得了 2 MB/s 的吞吐量。Microsoft Visual C++ 2010 (/O2) 使相同代码的速度达到 40 MB/s。

After rewriting the IO to pure C while (fgets(buf, 100, stdin))the throughput jumped to 90 MB/s in both tested compilers. That makes a difference for any input bigger than 10 MB...

将 IO 重写为纯 C 语言后while (fgets(buf, 100, stdin)),两个测试编译器的吞吐量都跃升至 90 MB/s。对于任何大于 10 MB 的输入,这都会有所不同......

回答by derpface

Wait, am I understanding you correctly? You're using cin for keyboard input, and you want to stop reading input when the user enters the EOF character? Why would the user ever type in the EOF character? Or did you mean you want to stop reading from a file at the EOF?

等等,我对你的理解正确吗?您正在使用 cin 进行键盘输入,并且您想在用户输入 EOF 字符时停止读取输入?为什么用户会输入 EOF 字符?或者您的意思是要停止从 EOF 读取文件?

If you're actually trying to use cin to read an EOF character, then why not just specify the EOF as the delimiter?

如果您实际上尝试使用 cin 来读取 EOF 字符,那么为什么不指定 EOF 作为分隔符呢?

// Needed headers: iostream

char buffer[256];
cin.get( buffer, '\x1A' );

If you mean to stop reading from a file at the EOF, then just use getline and once again specify the EOF as the delimiter.

如果您打算在 EOF 处停止读取文件,则只需使用 getline 并再次指定 EOF 作为分隔符。

// Needed headers: iostream, string, and fstream

string buffer;

    ifstream fin;
    fin.open("test.txt");
    if(fin.is_open()) {
        getline(fin,buffer,'\x1A');

        fin.close();
    }

回答by 0xbadf00d

One option is to a use a container, e.g.

一种选择是使用容器,例如

std::vector<char> data;

and redirectall input into this collection until EOFis received, i.e.

重定向所有输入到该集合,直到EOF被接收,即

std::copy(std::istream_iterator<char>(std::cin),
    std::istream_iterator<char>(),
    std::back_inserter(data));

However, the used container might need to reallocate memory too often, or you will end with a std::bad_allocexception when your system gets out of memory. In order to solve these problems, you could reservea fixed amount Nof elements and process these amount of elements in isolation, i.e.

但是,使用过的容器可能需要过于频繁地重新分配内存,否则std::bad_alloc当您的系统内存不足时,您将以异常结束。为了解决这些问题,您可以保留固定数量N的元素,并隔离处理这些数量的元素,即

data.reserve(N);    
while (/*some condition is met*/)
{
    std::copy_n(std::istream_iterator<char>(std::cin),
        N,
        std::back_inserter(data));

    /* process data */

    data.clear();
}

回答by Bryan

while(std::cin) {
 // do something
}