c语言cin读取一行txt,关于输入:如何在C ++中从cin读取到EOF

没有检索到摘要

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

您可以从标准输入中读取可变数量的数据的唯一方法是使用循环。我一直发现std::getline()函数工作得很好:

std::string line;

while (std::getline(std::cin, line))

{

std::cout << line << std::endl;

}

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

这里要注意的一点是,当您从通过stdin传递的文件中读取内容时,这和给出的大多数答案将在输入的末尾附加一个换行符。并非所有文件都以换行符结尾,但是循环的每次迭代都会在流中附加" std :: endl"。在大多数情况下,这可能不是问题,但是如果文件完整性成为问题,则可能会再次咬住您。

这不应该是最受支持的答案。请参阅以下社区Wiki答案。另外,也许看到以下问题:stackoverflow.com/questions/3203452/

通过使用流迭代器,可以在没有显式循环的情况下进行操作。我确定它在内部使用了某种循环。

#include

#include

#include

#include

#include

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 it(std::cin);

std::istream_iterator end;

std::string results(it, end);

std::cout << results;

}

尼斯。至于"我确定它在内部使用了某种循环"-任何解决方案都可以。

这似乎从输入中删除了换行符,即使它们出现在中间。

使用循环:

#include

using namespace std;

...

// numbers

int n;

while (cin >> n)

{

...

}

// lines

string line;

while (getline(cin, line))

{

...

}

// characters

char c;

while (cin.get(c))

{

...

}

资源

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

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

#include

#include

#include

int main()

{

std::istreambuf_iterator begin(std::cin), end;

std::string s(begin, end);

std::cout << s;

}

这可能应该是规范的答案。

Downvoted。那么,与KeithBs解决方案相比,优缺点是什么?是的,您使用的是std::istreambuf_iterator而不是std::istream_iterator,但是为什么呢?

std :: istreambuf_iterator默认情况下跳过空格,并且可以更快

可能最简单且通常有效:

#include

int main()

{

std::cout << std::cin.rdbuf();

}

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

你们已经知道,但可能对某些人有所帮助:std::ostringstream std_input; std_input << std::cin.rdbuf(); std::string s = std_input.str()。您将所有输入都放在s中(如果输入太大,请小心使用std::string)

悲伤的旁注:我决定使用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的输入,这都是有区别的...

无需将代码重写为纯C语言,只需在while循环之前添加std::ios::sync_with_stdio(false);即可。如果您交错阅读和写作,cin.tie(NULL);也可能会有所帮助。

您可以使用std :: istream :: getline()(或者最好是对std :: string起作用的版本)函数来获取整行。两者都有允许您指定定界符(行尾字符)的版本。字符串版本的默认值为" n"。

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

std::vector data;

并将所有输入重定向到该集合中,直到收到EOF,即

std::copy(std::istream_iterator(std::cin),

std::istream_iterator(),

std::back_inserter(data));

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

data.reserve(N);

while (/*some condition is met*/)

{

std::copy_n(std::istream_iterator(std::cin),

N,

std::back_inserter(data));

/* process data */

data.clear();

}

等一下,我理解正确吗?您将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();

}

while(std::cin) {

// do something

}

这是一个可怕的答案灾难,因为它实际上保证会导致错误的代码。

@KerrekSB为什么实际上保证会导致错误的代码?

@Mat?Ferech:因为它强烈建议do something不包含I / O操作返回值的其他检查,所以它包含的检查毫无意义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值