简体   繁体   中英

C++ cin didn't get line

I have a program where I'm specifying the file to be read using cin, so I run the program ./prog < file.txt, but in the following code, cin doesn't grab anything. Could someone explain why line is empty after the code executes?

 void Building::build(){
    char mode;
    cin >> mode >> sizeFloors >> numFloors;

    if(mode == 'M')
        readMap(sizeFloors, numFloors);

}

^^ this executes fine

void Building::readMap(int floorSize, int numFloors){

    string line;
    int curFloor(numFloors - 1);

    while( curFloor >= 0 ){
        cin >> line;

        if(line.empty()){
            cout << "Error: input file too short" << endl;
            exit(1);
        }
    }   

^^ here line.empty() returns true

this is the input file

M
4
1
WWWW
WWWW
WWWW
WWWW

so clearly line shouldnt return empty

When mixing formatted input (ie, using operator>>() ) and unformatted input (eg, std::getline() ) you need to make sure that you are at a location you are interested in. The formatted input operators stop reading the moment their format is satisfied. For example, reading a character just reads that one character. Any following charactters, eg, a newline, is left in the input. std::getline() stops reading at the first newline received. I guess, after you entered your menu selection you hit newline and this is where std::getline() stops (same if the menu selection is in a file on its own).

A typical approach when switching between formatted and unformatted I/O is to skip all leading spaces:

std::getline(std::cin >> std::ws, line);

Alternatively, you can ignore everything up to and including the first newline:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Which approach is used clearly depends on the content of your data. For example, if you want to read code where leading namespace matters skipping up to the first non-whitespace is not an award winning idea. However, in many situations using std::ws works just fine.

This might help you ...

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
  string line;
  ifstream myfile ("example.txt");
  if (myfile.is_open())
  {
    while ( myfile.good() )
    {
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }

  else cout << "Unable to open file"; 

  return 0;
}

The >> operator, when reading a std::string is taking spaces as string separator, see here .

You might want to use getline instead.

And you might (eg on Linux) compile your code with all warnings and debugging information (eg with g++ -Wall -g ) then use a debugger (eg gdb ) to find out what is happening.

I would suggest to line.clear() inside the loop.

I also find writing int curFloor(numFloors - 1); less readable than int curFloor = numFloors - 1;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM