-1

I'm new to C++ programming and trying to figure out a weird line read behavior when reading a line from a text file. For this specific program, I have to wait for the user to press enter before reading the next line.

If I hard code the file name, the file read starts at line 1 as expected:

#include <iostream>
#include <fstream>
using namespace std;

int main(void) {
   ifstream in_file;
   in_file.open("test.txt");

   // read line by line
   string line;

   while (getline(in_file, line)) {
      cout << line;
      cin.get();
   }

   in_file.close();
   return 0;
}

I compile with g++ -Wall -std=c++14 test1.cpp -o test1 and get:

$ ./test
This is line one.
**user presses enter**
This is line two.
**user presses enter**
This is line three.
etc. etc.

But when I add in the option to have the user type in a file name, the line read starts at line 2:

#include <iostream>
#include <fstream>
using namespace std;

int main(void) {
   string filename;
   cin >> filename;   

   ifstream in_file;
   in_file.open(filename);

   // read line by line
   string line;

   while (getline(in_file, line)) {
      cout << line;
      cin.get();
   }

   in_file.close();
   return 0;
}

The same compile command gives me:

$ ./test2
test.txt
This is line two.
**user presses enter**
This is line three.
**user presses enter**
This is line four.
etc. etc.

Am I missing something here? I have no idea why it starts reading at line 2 when I add in the code to specify a file name. Am I not finishing the cin statement properly or something?

Thanks!

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
redsh1rt
  • 33
  • 4
  • 3
    I can not reproduce this. Your code will not pause between line one and line two because `cin` will have an extra "new line" character left over from entering the file name, but that should only cause the two lines to be printed on the same line without stopping. You can fix that with `cin.ignore()` which will clear out the extra character. – Lev M. Nov 28 '21 at 22:45
  • Ah, interesting. I was wondering if it was something like a new line character messing things up. Putting ```cin.ignore()``` right before my while loop worked. Thanks! – redsh1rt Nov 28 '21 at 23:35
  • Found the answer to my question in this other thread: https://stackoverflow.com/questions/25475384/when-and-why-do-i-need-to-use-cin-ignore-in-c – redsh1rt Nov 28 '21 at 23:41
  • `cin >> filename;` Try use file name with whitespaces. another error in your code – arutar Nov 28 '21 at 23:45
  • 1
    Use `std::getline()` to read in the filename, not `operator>>` – Remy Lebeau Nov 28 '21 at 23:48
  • Thanks, I did some reading on ```std::getline()``` and that makes much more sense now. – redsh1rt Nov 28 '21 at 23:58

2 Answers2

1

This implementation of the code should work. You just needed to add cin.ignore() to ignore the remaining characters on the line until you hit either the end of the line(EOL) or the end of the file(EOF). The function also takes in 2 parameters, which are the maximum number of characters to ignore and the character to ignore. link to the use of cin.ignore(). Hope that this helps :)

#include <iostream>//basic
#include <fstream>//file

using namespace std;

int main(){
    //set file name
    string file="";
    cout<<"file name: ";
    cin>>file;

    //create/write to file
    ofstream out_file;
    out_file.open(file);
    out_file<<"test 1\ntest 2\ntest 3";
    out_file.close();

    //read file
    ifstream in_file;
    in_file.open(file);

    string line;

    cin.ignore();//clear buffer

    while(getline(in_file,line)){
        cout<<line;
        cin.get();
    }

    in_file.close();

    system("pause");

    return 0;
}
  • Elaborate how that answers the question, and what specifically went wrong with the OPs code. Code only answers aren't very useful without any further explanation! – πάντα ῥεῖ Nov 28 '21 at 23:08
  • Ok, thanks for the feedback. I just did. I was just trying to get the answer out there for people who needed it. I was creating a comment for what I changed, etc.. Sorry, this is my first response and I was just trying to help. – badger code Nov 28 '21 at 23:16
  • I was trying to figure out how to add comments as well as the code in the response/answer. That's why I could only post the code until I figured out how to include the elaboration :) – badger code Nov 28 '21 at 23:29
  • Thanks! I never thought to put in a ```cin.ignore()``` right before my while loop. That fixed my issue. Why would I need to add that? Is it something to do with new line characters? – redsh1rt Nov 28 '21 at 23:37
  • Found the reason why: https://stackoverflow.com/questions/25475384/when-and-why-do-i-need-to-use-cin-ignore-in-c – redsh1rt Nov 28 '21 at 23:42
  • 1
    The link that I included in the comment should go more in depth and explains how the "getline()" gets affected from the "cin", etc. But from what I can understand, it appears that the user inputs a newline that gets added into the input buffer, so the first getline() reads the 2nd line because the user inputted a newline previously when they hit enter, so it terminates that command. The "cin.ignore()" gets rid of the extra characters from the "cin" command, so the "\n"(newline char.) that formed from the user pressing enter no longer exists in the input buffer. Hope that this makes sense :) – badger code Nov 28 '21 at 23:51
  • Also, you should be eligible to put the "cin.ignore()" anywhere after the "cin>>file" because it just needs to clear the buffer from the user hitting enter after the "cin>>file", but I just chose to put it before the while loop. – badger code Nov 28 '21 at 23:59
  • Thanks! I did some more reading on ```std::getline()``` and it makes way more sense to me now. – redsh1rt Nov 29 '21 at 00:01
1

by default cin operator>> reads data up to the first whitespace characte and whitespace characte is not extracted reference. So if you read file name like this cin>>file; file variable will contains only first part of your string without whitespace. So that when reading you do not have such problems use getline

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main(void) {
    string filename;

    getline(cin, filename, '\n');

    ifstream in_file;
    in_file.open(filename);

    // read line by line
    string line;

    while (getline(in_file, line)) {
        cout << line;
        cin.get();
    }

    in_file.close();
    return 0;
}
arutar
  • 1,015
  • 3
  • 9