0

Lets say I have a text file containing something like:

Four

score

and

seven

years

ago

...

I want to be able to label these lines so that after the program runs, the file looks like:

1.Four

2.score

3.and

4.seven

5.years

6.ago

...

I've prepared a solution; however, I find it to be heavy weight and it has a problem of labeling one past the last line...

std::string file = "set_test - Copy.txt";
        std::ifstream in_test{file};
        std::vector<std::string> lines;
        while(in_test) {
            std::string temp;
            getline(in_test, temp);

            lines.push_back(temp);
        }
        in_test.close();

        std::ofstream out_test{file};
        for(unsigned int i = 0; i < lines.size(); ++i) {
            out_test << i+1 << '.' << lines[i] << '\n';
        }

On top of being heavy-weight, this solution also labels the line beyond the last line of text.

Does anyone have a better solution to this problem?

Alden Bernitt
  • 119
  • 1
  • 1
  • 7

1 Answers1

0

The cause of your problem is this structure

while (stream is good)
    read from stream
    do something

as it will read too much. (See this Q&A for explanation.)
What's happening is that the very last getline, the one that actually reaches the end of the file, will fail and leave temp empty.
Then you add that empty line to your lines.

The "canonical" stream-reading loop structure is

while (attempt to read)
    do something with the result

in your case,

std::string temp;
while (getline(in_test, temp)) {
    lines.push_back(temp);
}

If you write to a different file you don't need to store anything except the last line; you can write each line immediately.
If you want to replace the original, you can replace the old with the new afterwards.
Something like this:

std::ifstream in_test{"set_test - Copy.txt";}
std::ofstream out_test{"set_test - Numbered.txt"};
if (!in_test || !out_test) {
    std::cerr << "There was an error in the opening of the files.\n";
    return;
}

int i = 1;
std::string line;
while (getline(in_test, line) && out_test << i << '.' << line << '\n') {
    i++;
}
Community
  • 1
  • 1
molbdnilo
  • 55,783
  • 3
  • 31
  • 71