我正在编写一个直接从用户输入读取数据的程序,并且想知道在标准输入的EOF之前我怎么能(没有循环)读取所有数据。我正在考虑使用cin.get( input, '\0' )
,但'\0'
并不是真正的EOF字符,只能在EOF或'\0'
之前读取,以先到者为准。
或者使用循环是唯一的方法吗?如果是这样,最好的方法是什么?
答案 0 :(得分:61)
从stdin读取可变数据量的唯一方法是使用循环。我总是发现std::getline()
函数效果很好:
std::string line;
while (std::getline(std::cin, line))
{
std::cout << line << std::endl;
}
默认情况下,getline()读取直到换行符。您可以指定另一个终止字符,但EOF本身不是一个字符,因此您不能简单地调用getline()。
答案 1 :(得分:46)
您可以使用流迭代器在没有显式循环的情况下执行此操作。我确信它在内部使用某种循环。
#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;
}
答案 2 :(得分:40)
使用循环:
#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))
{
...
}
答案 3 :(得分:21)
在使用std::istream_iterator
研究KeithB的解决方案后,我发现了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;
}
答案 4 :(得分:5)
可能最简单,效率最高:
#include <iostream>
int main()
{
std::cout << std::cin.rdbuf();
}
如果需要,可以使用其他类型的流(如std::ostringstream
)作为缓冲区而不是标准输出流。
答案 5 :(得分:2)
您可以使用std::istream::getline()(或最好是version that works on std::string)函数来获取整行。两者都有允许您指定分隔符(行尾字符)的版本。字符串版本的默认值为'\ n'。
答案 6 :(得分:2)
可悲的是,我决定使用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。
在将IO重写为纯C while (fgets(buf, 100, stdin))
后,两个经过测试的编译器的吞吐量都跃升至90 MB / s。这对任何大于10 MB的输入都有所不同......
答案 7 :(得分:0)
while(std::cin) {
// do something
}
答案 8 :(得分:0)
等等,我理解正确吗?您正在使用cin进行键盘输入,并且您想在用户输入EOF字符时停止读取输入?为什么用户会输入EOF字符?或者你的意思是你想停止阅读EOF中的文件?
如果您实际上尝试使用cin来读取EOF字符,那么为什么不将EOF指定为分隔符呢?
// Needed headers: iostream
char buffer[256];
cin.get( buffer, '\x1A' );
如果你想在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();
}
答案 9 :(得分:0)
一种选择是使用容器,例如
std::vector<char> data;
和重定向所有输入到此集合中,直到收到EOF
,即
std::copy(std::istream_iterator<char>(std::cin),
std::istream_iterator<char>(),
std::back_inserter(data));
但是,使用过的容器可能需要经常重新分配内存,否则当系统内存不足时,您将以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();
}