如何读取文件并将其写入字符串C++
我找到了一个解决方案,但我相信有更好的方法可以做到这一点。如何在不使用复杂工具的情况下改进代码?
string Read(string& file) {
ifstream in;
string text;
string s;
in.open(file, ios::in);
try {
while (!in.eof()) {
text.append(s);
in >> s;
}
}
catch (exception& ex) {
cout << ex.what();
}
in.close();
return text;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的代码读取了空格分离的单词,丢弃了空格,并将所有单词连接成一个没有空格的字符串。您可能想逐字阅读文件内容。
将整个文件读取到
std :: String
无循环的一种方法是使用std :: String
constructor> constructor,该构建器带有两个迭代器 - 构造函数为您执行循环。用std :: istreambuf_iterator
:另一种选择是将文件映射到内存(零copy方法),例如使用
boost :: iostreams :: iostreams :: mapped_file_file
它曾经得到。该方法对于大于〜100KB的文件的速度更快,基准获得了硬数字。一个优化是立即填充文件映射的所有页面,而不是需求分页首先访问。
例子:
Your code reads whitespace-separated words, discards the whitespace, and concatenates all words into one string with no whitespace. You probably want to read the file content verbatim.
One way to read an entire file into a
std::string
without a loop is to usestd::string
constructor which takes two iterators - the constructor does the loop for you. Invoke it withstd::istreambuf_iterator
:Another alternative is to map the file into memory (zero-copy method), e.g. using
boost::iostreams::mapped_file
, that's as clean and efficient as it ever gets. The method is faster for files larger than ~100kB, benchmark to get hard numbers.An optimization would be to populate all the pages of the file mapping immediately, rather than with demand paging on first access.
Example:
最简单的方法(通常意味着最好的方法)是一次读取文件一个字符
The simplest way (which often times means the best way) is to read the file one character at a time
循环
是错误的,因为条件
while(!in.eof())
即使以前的语句 in&gt;&gt; S 成功。最好写,而(!in.fail())
而不是while(!in.eof())
。但是,像这样编写循环会更清晰,效率更高:
这种循环条件间接使用
in.operator bool()
,这等同于!in.fail()
。该循环比另一个循环更有效的原因是,在另一个循环的第一次迭代中,总是会附加一个空字符串。在这个循环中不再是这种情况。
尽管您没有在问题的评论部分中指出这一点,但您表示,要保留空格字符而不是被丢弃是可取的。在这种情况下,您不应使用
操作员/code>
用于阅读输入,一次读取一个单词,但您应该使用
std :: getline
,一次读取一行:The loop
is wrong, because the condition
while (!in.eof())
may befalse
even when the previous statementin >> s
succeeded. It would be better to writewhile (!in.fail())
instead ofwhile (!in.eof())
.However, it would be clearer and slightly more efficient to write the loop like this:
This loop condition indirectly uses
in.operator bool()
, which is equivalent to!in.fail()
.The reason why this loop is a bit more efficient than the other loop is that in the first iteration of the other loop, an empty string was always appended. This is no longer the case in this loop.
Although you did not state this in the question, in the comments section of your question, you stated that it would be preferable for the whitespace characters to be retained instead of being discarded. In that case, you should not be using
operator >>
for reading input, which reads one word at a time, but you should rather be usingstd::getline
, which reads one line at a time: