Question

I'm using this code to extract certain part of each line of a text file:

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();
} 

But when I run the code, the result is not as I expect it to be. Only the last string is being written to the file. If I use this instead:

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

I get the exact output I need. I do not understand what is the difference.

Was it helpful?

Solution 2

Move file open and file close operations outside while loop:

#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();
}

And replace

fmatch << out1;

with

fmatch << out1 << endl;

if you need cout and fmatch agreement.

OTHER TIPS

Well, ofstream probably overwrites existing contents every time you open it. I mean, every time you open file, write pointer will be placed at the begninning, so even without ios::trunc flag new data written into that file will overwrite existing contents.

To solve the problem, stop reopening ofstream twice for every line of text. File open operation can be slow.

Either that, or try using ios::app flag.

std::ofstream fmatch("solo_matches.txt", ios::out);
fmatch << ...;
fmatch.close();

opens the file, rewrites its content and saves it upon closing the stream. To append the content at the end of the file, you can use ios::app flag:

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

or yet even better, instead of reopening the file in every iteration:

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

you could do:

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

Also note that this line:

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

relies on the correct format of the input, it would be safer to check the return value of 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 );
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top