3

I'm running the following program

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

int main(int argc, char *argv[])
{
    ifstream input_file(argv[1]);
    vector<string> words;
    string line;

    while(getline(input_file, line))
    {
        cout << line << endl;
        words.push_back(line);
    }
    input_file.close();

    cout << "First and last word: " << words[0] << " " << words.back() << endl;

    return 0;
}

using the following text file as an input

permission
copper
operation
cop
rationale
rest

and I get the following output in terminal

permission
copper
operation
cop
rationale
rest

 rest and last word: permission

Why is the last word words.back() printed at the beginning of the line while erasing some of the text?

jroy
  • 191
  • 1
  • 1
  • 8
  • https://stackoverflow.com/questions/45956271/stdgetline-reads-carriage-return-r-into-the-string-how-to-avoid-that – Renat Aug 04 '20 at 14:05
  • `ifstream input_file(argv[1]);` -- Basically, you told a fib to the file I/O library and stated the file is a text file, when it isn't a text file. Once you did that, expect all sorts of weird things to happen. – PaulMcKenzie Aug 04 '20 at 14:07
  • I'm surprised you get that extra line, though... – Asteroids With Wings Aug 04 '20 at 14:45
  • @PaulMcKenzie It _is_ a text file, and telling the lib that it's a binary file won't fix this issue. – Asteroids With Wings Aug 04 '20 at 14:45
  • What I am saying is that as far as the I/O library is concerned, the file is not what would be considered a text file due to the line endings. It essentially is a "binary" file. – PaulMcKenzie Aug 04 '20 at 14:50

1 Answers1

6

Because your file has Windows line-endings ("\r\n") and you're on Linux or Mac (which doesn't translate these into "\n").

std::getline is only trimming the '\n's for you. So, \r is left at the end of each of your strings; in many consoles, '\r' moves the write cursor to the start of the line. Then, the " " << words.back() part overwrites the already-written "First and last word: " << words[0] part.


Example:

  • First word is permission␍
  • Last word is rest␍

(Note the control character at the end of each word!)

┌───────────────────┬──────────────────────────────────────┐
│                   │  ⭭⭭⭭⭭⭭                               │
│ Write "First"     │  First                               │
│                   │       ꕯ                              │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│                   │       ⭭⭭⭭⭭                           │
│ Write " and"      │  First·and                           │
│                   │           ꕯ                          │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│                   │           ⭭⭭⭭⭭⭭                      │
│ Write " last"     │  First·and·last                      │
│                   │                ꕯ                     │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│                   │                ⭭⭭⭭⭭⭭⭭                │
│ Write " word:"    │  First·and·last·word:                │
│                   │                      ꕯ               │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│                   │                      ⭭⭭⭭⭭⭭⭭⭭⭭⭭⭭⭭␍    │
│ Write first word  │  First·and·last·word:·permission     │
│                   │  ꕯ                                   │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│                   │  ⭭                                   │
│ Write " "         │  ·irst·and·last·word:·permission     │
│                   │   ꕯ                                  │
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
│                   │   ⭭⭭⭭⭭␍                              │
│ Write last word   │  ·rest·and·last·word:·permission     │
│                   │  ꕯ                                   │
└───────────────────┴──────────────────────────────────────┘

Solution

You can strip this from the end of each line yourself, or preprocess the file externally.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35