0

I'm extracting some data from a text file and put them in 2 vectors but the output of std::getline() is not as I expected. Here's the code:

std::vector<std::string> v1;
std::vector<std::string> v2;

const char* filename = "words.txt";
std::ifstream fin(filename);
  
if (!fin) {
    throw "Bad file name!";
}
else {
    // File is good
    std::string temp;
    while (std::getline(fin, temp)) {
      std::cout << "(((Temp: " << temp << ")))" << std::endl;
      v1.push_back(temp.substr(0, temp.find(' ')));
      // Erase first character
      temp.erase(0, temp.find(' ') + 1);
      // Erase spaces
      v2.push_back(temp.substr(temp.find_first_not_of(' '),temp.find_last_not_of(' ') - temp.find_first_not_of(' ') + 1));
    }
}

// output v1:
std::cout << "\nValues of v1:\n";
for (auto word : v1){
   std::cout << "(((" << word << ")))" << std::endl;
}

// output v2:
std::cout << "\nValues of v2:\n";
for (auto word : v2){
   std::cout << "(((" << word << ")))" << std::endl;
}

Here's the "words.txt":

a    A
b        B
c    C
d         D
e       E

The real words.txt is more complicated but similar.

And here's the output:

)))Temp: a    A
)))Temp: b        B
)))Temp: c    C
)))Temp: d         D
)))Temp: e       E

Values of v1:
(((a)))
(((b)))
(((c)))
(((d)))
(((e)))

Values of v2:
)))A
)))B
)))C
)))D
)))E

Why is there a difference in the output from each line read from the file and between the 2 vectors?

  • Because this is what the program does? It's fairly complicated way of removing the intervening whitespace between the two words on each line. It's a pretty fragile, inefficient, and error-prone way of doing so, but that's what it does. – Sam Varshavchik Jun 28 '20 at 21:33
  • Is there any way around this? I need the data in the second vector but this kinda messes up all of them and I cannot use it the way I want. – Triet Minh Nhan Jun 28 '20 at 21:41
  • Looks like your words.txt file has CRLF end-of-lines. You might want to trim the CR off the end of the line, first thing after doing the getline. – Eljay Jun 28 '20 at 22:08

1 Answers1

0

In v2, the values end with a carriage return (\r). When this is printed to the terminal, it makes the cursor go back to the beginning of the line, so the ))) is printed over top of the (((. The same thing happens when the temp values are displayed, because it displays the entire line.

Please also see Getting std :: ifstream to handle LF, CR, and CRLF? .

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153