为啥 fstream 在这里不起作用(在文件中读/写)?

Posted

技术标签:

【中文标题】为啥 fstream 在这里不起作用(在文件中读/写)?【英文标题】:Why is fstream not working here (reading/writing in a file)?为什么 fstream 在这里不起作用(在文件中读/写)? 【发布时间】:2021-04-18 10:53:16 【问题描述】:

我在使用 fstream 时遇到了问题。我第一次在文件中写入和读取它正在工作,但第二次不是。

这是我第一次这样做:

std::ifstream stream(Window::FILE);
    std::string input;

    if (!stream.is_open())
        std::cout << "PROBLEM OPENING THE FILE\n";

    std::getline(stream, input); // checking if the file is empty
    if (input.empty()) 
        // if empty rewrite the information
        std::ofstream streamInput(Window::FILE);
        streamInput << "Digits\nDragGame: 0\nSoundGame: 0\nFallingGame: 0\n" 
            << "\nFigures\nDragGame: 1\nSoundGame: 0\nFallingGame: 0\n"
            << "\nColors\nColor: 0\n"; 
        streamInput.close();
     else 
        // if not get it
        std::ifstream streamOutput(Window::FILE);
        std::vector<std::pair<std::string, int>> info;

        std::string input, header;
        std::string output;

        bool isHeader = true;
        while (std::getline(streamOutput, input)) 
            if (input == "") 
                isHeader = true;
                continue;
            

            if (isHeader) 
                header = input;
                isHeader = false;

                continue;
            
            bool flag = false;

            int level = 0;
            std::string word;
            for (int i = 0; i < input.size(); i++) 

                if (input[i] == ' ')
                    continue;

                if (input[i] == ':')
                    flag = true;
                else if (!flag)
                    word += input[i];
                else
                    level = level * 10 + (input[i] - '0');
            
            Singleton::table.getInfo()[header].push_back(level);
        
        
        streamOutput.close();
    
    stream.close();

我将我的信息保存在我的表结构中。如果我的 main.cpp 中有新信息,我会尝试添加新信息:

std::ofstream streamInput(Window::FILE);
    std::ifstream g(Window::FILE);
    g.open(Window::FILE);

    g.clear();

    auto& k = Singleton::table.getInfo();
    std::vector<std::pair<std::string, int>> info;

    std::string input, header;
    std::string output;

    int game = 0;
    while (std::getline(g, input)) 
        if (input.empty() || k.find(input) != k.end()) 
            header = input;
            output += input + "\n";
            game = 0;
            continue;
        
        bool flag = false;

        int level = 0;
        std::string word;
        for (int i = 0; i < input.size(); i++) 

            if (input[i] == ' ')
                continue;

            if (input[i] == ':')
                flag = true;
            else if (!flag)
                word += input[i];
            else
                level = level * 10 + (input[i] - '0');
        
        output += word + ":" + std::to_string(k[header][game++]);
    
    streamInput.clear();

    streamInput << output;

但有时文件无法加载。我确信我传递了正确的文件,而且当我使用 .clear() 方法时,有时它可以正常工作,有时不能。 fstream.is_open() 返回 false。

什么会导致这样的问题?

【问题讨论】:

抱歉,我尝试了 20 个,但 *** 试图玩聪明,不允许我发送它。它说它想要更好的,所以我尝试输入随机单词并且它成功了。它发送的那一刻我设法改变它。 std::getline(stream, input); // checking if the file is empty - 这太可怕了!如果输入的第一行为空怎么办?你会重写它的内容!此外,代码缩进很糟糕(第一行看起来像函数声明) std::ofstream streamInput(Window::FILE); 在第一个 sn-p 中可能会失败,因为 stream 仍然保持文件打开。与std::ifstream streamOutput(Window::FILE); 相同,在这两种情况下,您都不检查打开文件是否真的成功。 fstream.is_open() 返回 false。”文本fstream.is_open() 没有出现在所示代码中的任何位置。 在第二个片段中,您还尝试使用不同的流对象多次打开同一个文件,如std::ofstream streamInput(Window::FILE); std::ifstream g(Window::FILE);。这一般是行不通的。打开要读取的文件,从中读取,关闭它。然后打开文件进行写入,写入,关闭。或者,使用单个fstream 对象进行读写,打开一次(但不要忘记在读写之间寻找正确的位置)。 【参考方案1】:

考虑一下:

std::ofstream streamInput(Window::FILE);
std::ifstream g(Window::FILE);
g.open(Window::FILE);
g.clear();

你正在做的是

    打开一个文件写入 打开 THE SAME 文件进行读取,并将其与不同的流相关联。

第 2 步必须失败。清除失败标志没有帮助。 g.clear() 就像死人脸上的口红。任何通过g 读取任何内容的尝试都注定要失败。

因此,解决方案是:不要尝试将两个流与同一个文件相关联,尤其是当其中一个流要写入时。当您写入时,然后写入,然后关闭流。只有这样才能打开阅读。

还可以打开一个文件进行读写,std::fstream,请参阅:https://en.cppreference.com/w/cpp/io/basic_fstream,但我怀疑它是您正在寻找的。也就是说,不要使用fstream 来掩盖您处理数据流的不良设计。几乎可以肯定,您想要实现的目标可以通过标准 ifstreamofstream 实现。

编辑

显然可以将两个流附加到一个文件,但结果取决于操作系统。如果你的程序在我的机器上运行,第一条指令会清空文件内容,所以打开g时只能看到一个空文件,所以一直处于eof状态,就好像两个流被分叉了。

见:FIO24-C. Do not open a file that is already open

【讨论】:

以上是关于为啥 fstream 在这里不起作用(在文件中读/写)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 jQuery 选择器在这里不起作用?

为啥 findmany() 在这里不起作用 - Lumen/Laravel?

为啥 Z-index 在这里不起作用? [复制]

为啥此样式代码在样式标签之间不起作用?

这里有啥问题,为啥 innerHTML 不起作用? [关闭]

html中,为啥有的css样式在样式表里不起作用?!