为啥从 C++ 中读取文件时未显示附加内容?
Posted
技术标签:
【中文标题】为啥从 C++ 中读取文件时未显示附加内容?【英文标题】:Why is Appended content not showing up on reading from a file in C++?为什么从 C++ 中读取文件时未显示附加内容? 【发布时间】:2021-10-18 18:42:38 【问题描述】:请先看这段代码,然后我会问我的问题。
#include <bits/stdc++.h>
#include <fstream>
using std::cout;
using std::cin;
using std::endl;
int main()
std::ofstream out_file ("outfile.txt"); /* creates a outfile.txt */
if (!out_file) // checks files existence
std::cerr << "Error bruh!" << endl;
return (1);
int num = 100;
double total = 456.78;
std::string name = "atik";
out_file << num << "\n" // writing to the file
<< total << "\n"
<< name << endl;
/* Reading from file, because i want to! - */
std::ifstream in_file("outfile.txt"); // will open outfile for reading.
char c;
while (in_file.get(c))
cout << c;
/*
Output (as expected) -
100
456.78
atik
Right Now My **output.txt** file is - (as expected)
100
456.78
atik
*/
/* Appending the file that we just created - */
std::ofstream out_file2 ("outfile.txt", std::ios::app);
cout << "\nEnter something to write in file : " << endl;
std::string line;
getline(cin, line);
out_file2 << line; // writes to out_file2
/* Reading from file again - */
std::ifstream in_file2("outfile.txt"); // will open outfile.txt for reading.
if( !in_file2 )
std::cerr << "File didn't open. Error encountered." << endl;
char ch;
cout << endl;
while( in_file2.get(ch) )
cout << ch;
/*
Output (unexpected? why?)-
100
456.78
atik
*/
in_file.close();
in_file.close();
out_file.close();
out_file2.close();
return 0;
现在,我的outfile..txt
是-(如预期的那样):
100
456.78
atik
Hello there
那么为什么in_file2
的输出没有显示Hello there
?为什么它会截断Hello there
?谁能解释一下?
【问题讨论】:
这只是一个大程序吗?在这种情况下,您需要关闭(或至少刷新)ofstreams,然后才能对写入文件做出任何保证。 我必须在哪一行刷新ofstream?如果您告诉我最好的(语法)方法,那将非常有帮助。谢谢 该死的@frank 非常感谢。因为有你,我今天可以安然入睡。我的问题已经解决,但我的疑问仍然存在。为什么我们需要在将行写入 out_file2 之后刷新流? @LearningNoob123:见my answer。问题在于用户模式缓冲区。 @LearningNoob123,因为您没有写入文件,所以您正在向负责写入文件的对象发送数据,并且它会在它喜欢的时候(或者当你强迫它这样做时)这样做。 【参考方案1】:out_file2<<line;
不会刷新(在前面的代码中使用 std::endl
会这样做),因此如果从 std::cin
读取的数据块少于完整块,则写入 out_file2
的数据可能会卡在您的用户中-mode 缓冲区(当您打开文件进行独立读取时不可见)。这些缓冲区通过在执行许多小型写入时减少系统调用的数量来提高 I/O 效率,以换取任何缓冲数据在该文件句柄之外不可见,直到缓冲区被刷新(通过填充隐式或显式通过手动刷新或关闭文件句柄)。
只需将该行更改为:
out_file2 << line << std::flush;
(或者在你完成后只是.close()
ing out_file2
)将导致它正确刷新,你应该在再次打开它以供读取时看到新数据。
【讨论】:
或者:使用范围让 RAII 负责清理 @ShadowRanger 非常感谢。它解决了我的问题,但您能否详细说明为什么我们需要在写入 out_file2 而不是写入 out_file 后刷新缓冲区?我有点明白你在括号中写了但仍然感到困惑,因为英语不是我的第一语言,所以非常感谢您进行一些详细说明。无论如何,谢谢你的时间先生。 @Frank:是的,通过在声明/使用out_file2
的代码段周围添加额外的花括号来隐式close
ing 也是合理的。
@LearningNoob123:用户模式缓冲基本上适用于所有编程语言。如果系统调用的开销是(由数字组成)500 ns(向内核发出从用户进程写入数据的信号),但在数组之间复制的每个字节只有 1 ns,如果您不使用用户模式缓冲,则输出一次一个字节将花费每个字节 501 ns,或超过 2 ms 来写入 4096 个字节;半秒写入 1 MB)。如果您改为缓冲 4096 个字节,然后对所有这些字节执行一次系统调用,则成本为 4096(写入用户缓冲区)+ 500 + 4096 ns ~= 8.7 μs(不到成本的 250 分之一)。
@ShadowRanger 哇!今天有很多东西要向你学习。非常感谢朋友:)以上是关于为啥从 C++ 中读取文件时未显示附加内容?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 glfw 窗口上没有使用 opengl 显示位图图像?在 C++ 中读取位图图像文件时出现问题
当从 html 文件中读取 Unicode 内容时,为啥 Unicode 字体无法在 QTextBrowser 中正确显示?