为啥从 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 的代码段周围添加额外的花括号来隐式closeing 也是合理的。 @LearningNoob123:用户模式缓冲基本上适用于所有编程语言。如果系统调用的开销是(由数字组成)500 ns(向内核发出从用户进程写入数据的信号),但在数组之间复制的每个字节只有 1 ns,如果您不使用用户模式缓冲,则输出一次一个字节将花费每个字节 501 ns,或超过 2 ms 来写入 4096 个字节;半秒写入 1 MB)。如果您改为缓冲 4096 个字节,然后对所有这些字节执行一次系统调用,则成本为 4096(写入用户缓冲区)+ 500 + 4096 ns ~= 8.7 μs(不到成本的 250 分之一)。 @ShadowRanger 哇!今天有很多东西要向你学习。非常感谢朋友:)

以上是关于为啥从 C++ 中读取文件时未显示附加内容?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 无法从文件中读取 UTF-8 西里尔文文本

为啥在 glfw 窗口上没有使用 opengl 显示位图图像?在 C++ 中读取位图图像文件时出现问题

C ++读取文件时未处理的异常

为啥 c++ ifstream 不能从设备读取?

当从 html 文件中读取 Unicode 内容时,为啥 Unicode 字体无法在 QTextBrowser 中正确显示?

为啥在尝试读取记录集字段时未定义访问 vba 抛出子或函数?