1

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?

Noe Cano
  • 483
  • 2
  • 5
  • 20
  • First please read [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). Then remember that the overloaded `>>` operator *skips* white-space. Perhaps you'd be interested to read about the [`std::noskipws`](https://en.cppreference.com/w/cpp/io/manip/skipws) manipulator. Lastly, don't use `char` arrays for your input, use `std::string`. – Some programmer dude Mar 14 '19 at 06:46

1 Answers1

1

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";
        }
Serge Ballesta
  • 121,548
  • 10
  • 94
  • 199