2

I'm trying to read all the lines of a given file.
For some reason, std::getline doesn't work as expected.
main.cpp:

#include <iostream>
#include <fstream>
#include <string>
int main() {
    std::string filePath = "../init.txt";
    std::ifstream inputFile(filePath);
    std::string str;
    int i = 0;
    while (std::getline(inputFile,str)) {
        std::cout << str << std::endl;
        i++;
    }
    std::cout << i << std::endl;
    inputFile.close();
    return 0;
}

../init.txt:

Game
battlefieldSize,100,200
players,2
soldiers,3
p1,human
normal,[2 3],M16
paramedic,[10 31]
sniper,[5 12],UZI
p2,computer,0
normal,[90 112],Missile
sniper,[90 113],M16
normal,[65 100],M16
Objects
weapon,M16,[5 5]
Armor,BodyArmor,0.8,[1 2]
weapon,Missile,[15 115]
solid,Tree,4,4,[20 20]

As you can see, I wanted to know how much times it's entering the loop, with variable i. The output is:

solid,Tree,4,4,[20 20]
1

Why is that happening?

Stav Alfi
  • 13,139
  • 23
  • 99
  • 171
Yinon
  • 945
  • 1
  • 8
  • 21
  • 1
    Can't duplicate on my desktop. – R Sahu Dec 22 '17 at 20:36
  • One of my friends actually had this kind of behaviour with `std::getline`. His code also was completely fine, but due to older version of IDE it compiled wrongly. Don't know how about you, OP, but if, by any chance, you are working on Code::Blocks and downloaded it from different source than original developer's, please redownload and reinstall it – Fureeish Dec 22 '17 at 20:38
  • Can't duplicate. Is there a problem with `std::string filePath = "../init.txt";`? Maybe you are reading another `init.txt` one directory level up? – j4nu5 Dec 22 '17 at 20:39
  • j4nu5 - no its the only file out there, if I'm trying to read with `inputFile >> str`, it prints the whole file, but every space as a newline – Yinon Dec 22 '17 at 20:40
  • Worked on my machine. What OS are you using? – Eljay Dec 22 '17 at 20:48
  • Eljay - MacOS Ron - I'm working with cmake, cant do that – Yinon Dec 22 '17 at 20:51
  • 2
    Your data file has the wrong kind of newlines in it. It uses `CR` as the newline, but `C++` uses `LF`. So the entire file is being read as a single line. – Barmar Dec 22 '17 at 20:52
  • I think Barmar has a very good guess. I made sure I saved init.txt with LF line endings (which is the default on my system). I've also tested it on macOS (10.13.2), and it worked there too. I've installed the latest Xcode. – Eljay Dec 22 '17 at 20:54
  • What does `cout << str.size() << endl;` show? – Barmar Dec 22 '17 at 20:54
  • Barmar - `cout << str.size() << endl;` is showing 287. I've tried to invalidate + restart – Yinon Dec 22 '17 at 20:56
  • From the command line, use `file ../init.txt` to see what line endings it has. (If they are LF, it will just say "ASCII text".) – Eljay Dec 22 '17 at 20:57
  • Eljay - the output is: `init.txt: ASCII text, with CR line terminators` – Yinon Dec 22 '17 at 20:59
  • What happens if you add CR delimiter `std::getline(inputFile,str,'\r')` – Killzone Kid Dec 22 '17 at 21:00
  • 1
    @Barmar You should probably turn that into an answer. – Ron Dec 22 '17 at 21:00
  • @Killzone Kid - `error: std::getline(inputFile,str,'\r') - no matching function` – Yinon Dec 22 '17 at 21:01
  • @Yinon you are not using C++11 or above? – Killzone Kid Dec 22 '17 at 21:03
  • @KillzoneKid yea.. this is from the cmake: set(CMAKE_CXX_STANDARD 11) – Yinon Dec 22 '17 at 21:06

1 Answers1

6

Your file has CR newlines instead of LF that is standard for Unix-style operating systems, so getline() is reading the entire file as a single line. You can fix the file in Terminal with:

tr '\r' '\n' < init.txt > newinit.txt
mv newinit.txt < init.txt
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • What favor are you asking for? If you mean an upvote, I've done that. – Barmar Dec 22 '17 at 22:34
  • I don't understand what you're talking about. What does that have to do with this question? – Barmar Dec 22 '17 at 22:50
  • Are you asking me to help with this question: https://stackoverflow.com/questions/47780622/mysql-left-join-incorrect-result – Barmar Dec 22 '17 at 22:51