Noe Cano
Noe Cano

Reputation: 515

Get content formatted from a text file in C ++

I have the following function that saves in a text file, content with certain format in the following way:

#include <fstream>   
#include <iostream> 
#include <iomanip>

int main () 
{
    using namespace std;

    fstream fs;
    string str1 = string("1");
    string str2 = string("12");
    string str3 = string("123");
    string str4 = string("1234");

    fs.open ("text.txt", std::fstream::in | std::fstream::out | std::fstream::app);

    fs << left << setfill(' ')
        << setw(10) << str1 << " | "
        << setw(10) << str2 << " | "
        << setw(10) << str3 << " | "
        << setw(10) << str4 << '\n';

    fs.close();

    return 0;
}

Once the following program has been executed, the following text is seen inside the file:

POS = 0123456789012345678901234567890123456789
TXT = 1       | 12      | 123     | 1234    |

And this function read the content of the file:

#include<iostream>
#include<fstream>

using namespace std;

int main() {

    ifstream myReadFile;
    myReadFile.open("text.txt");
    char output[100];
    if (myReadFile.is_open()) {
        while (!myReadFile.eof()) {
            myReadFile >> output;
        }
        cout<<output;
    }
    myReadFile.close();
    return 0;
}

The problem is that when I show the content of the output variable, it loses the format it had inside the text and it looks like this:

POS = 0123456789012345678901234567890123456789
TXT = 1|12|123|1234|

How can I get the text with the format it has inside the file?

Upvotes: 1

Views: 67

Answers (1)

Serge Ballesta
Serge Ballesta

Reputation: 148890

Only doing one single read inside the loop is the only acceptable use case for a while(file) loop. But while (!file.eof()) is allways wrong when followed with a formatted extractor operator or if there is any processing after the read operation. So stick to a good old infinite loop, and test after every read operation.

If you want to keep the spaces from the input line, for example to process a fixed size fields file, the simplest way IMHO is to read the line as a whole with std::getline:

#include <string>
...
    string output;
    if (myReadFile.is_open()) {
        for(;;) {
            getline(myReadFile, output);
            if (!myReadFile) break
            cout << output << "\n";
        }
        myReadFile.close();
    }

But in fact a single getline is an exception to the generic reading loop rule, and it would be more idiomatic to use:

        while (getline(myReadFile, output)) {
            cout << output << "\n";
        }

Upvotes: 1

Related Questions