【问题标题】:writing into file (std::ofstream) in a loop writes last line only在循环中写入文件 (std::ofstream) 仅写入最后一行
【发布时间】:2013-09-06 15:15:23
【问题描述】:

我正在使用这段代码来提取文本文件每一行的某些部分:

std::ifstream file( "infile.txt" );
std::string in1, out1;
int blockNumber = 0;

while( getline( file, in1 ) ) 
{   
    int n = 0;
    int i = 0;

    while( i <= blockNumber )
    {   
        n = in1.find_first_of("(", n + 1); 
        i++;
    }   
    out1 = in1.substr( n + 1, ( in1.find_first_of(")", n) - n - 1) );  
    ofstream fmatch ("solo_matches.txt",ios::out);
    fmatch.close();
    fmatch.open("solo_matches.txt");
    fmatch << out1;
    fmatch.close();
} 

但是当我运行代码时,结果并不像我预期的那样。只有最后一个字符串被写入文件。如果我改用这个:

 std::cout << out1 << std::endl;

我得到了我需要的确切输出。我不明白有什么区别。

【问题讨论】:

  • 那么你用来获得输出的输入是什么?
  • 为什么要构造ofstream,然后close,然后又构造open
  • fmatch.close(); fmatch.open("solo_matches.txt"); 当然可以完全删除,因为这两行与上一行正好相反。
  • 第一个while}在哪里?
  • 看起来你在每次输出后都关闭了流。你应该打开它一次,然后输出你想要的一切,然后关闭它。

标签: c++ file parsing file-io ofstream


【解决方案1】:

好吧,ofstream 可能会在您每次打开它时覆盖现有内容。我的意思是,每次打开文件时,写入指针都会放在开头,因此即使没有ios::trunc 标志,写入该文件的新数据也会覆盖现有内容。

要解决此问题,请停止为每行文本重新打开两次 ofstream。文件打开操作可能很慢。

要么这样,要么尝试使用ios::app 标志。

【讨论】:

  • +1 ios::out|ios::ate 也应该可以工作(虽然我已经做了一段时间了)。
  • @alby76 请点击他们答案旁边的复选标记“接受”对您帮助最大的答案。
【解决方案2】:

将文件打开和文件关闭操作移到while循环之外:

#include<iostream>
#include<fstream>

int main()
{
    std::ifstream file( "infile.txt" );
    std::string in1, out1;
    int blockNumber = 0;
    std::ofstream fmatch ("solo_matches.txt",std::ios::out);

    while( getline( file, in1 ) ) 
    {   
        int n = 0;
        int i = 0;

        while( i <= blockNumber )
        {   
            n = in1.find_first_of("(", n + 1); 
            i++;
        }   
        out1 = in1.substr( n + 1, ( in1.find_first_of(")", n) - n - 1) );  
        //fmatch.close();  //you don't need this
        //fmatch.open("solo_matches.txt"); //you don't need this
        std::cout << out1 << std::endl;
        fmatch << out1 << std::endl;
    }   
    fmatch.close();
}

然后替换

fmatch << out1;

fmatch << out1 << endl;

如果您需要coutfmatch 协议。

【讨论】:

  • 很好的解决方案,谢谢!通过这种方式,我得到了我需要的确切输出。
【解决方案3】:
std::ofstream fmatch("solo_matches.txt", ios::out);
fmatch << ...;
fmatch.close();

打开文件,重写其内容并在关闭流时保存。要将内容追加到文件末尾,可以使用ios::app 标志:

std::ofstream fmatch("solo_matches.txt", ios::out | ios::app);

或者甚至更好,而不是在每次迭代中重新打开文件:

while (...) {
    construct ofstream
    write to file
    close ofstream
}

你可以这样做:

construct ofstream
while (...) {
    write to file
}
close ofstream

还要注意这一行:

out1 = in1.substr( n + 1, ( in1.find_first_of(")", n) - n - 1) ); 

依赖于输入的正确格式,检查find_first_of的返回值会更安全:

std::size_t pos = in1.find_first_of(")", n);
if (pos != std::string::npos)
{
    out1 = in1.substr( n + 1, pos - n - 1 );
    ...
}

【讨论】:

  • 它现在可以与“ios::app”一起使用,谢谢!很有趣,但我确定输入是因为“infile.txt”是一个日志文件,我在另一个进程中验证它。
  • @alby76:但是为了将来这段代码的可维护性和可重用性,通常最好尽量减少代码的约束并尽可能少地依赖:)
猜你喜欢
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
相关资源
最近更新 更多