简体   繁体   中英

c++ getline() doesn't seem to operate correctly, Doesn't read the line till the end

I have tried using cin.ignore(); instead of the dummy variable, didn't help. content of the file looks like this:

D Name Surname

A Name2 Surname2

...

amount of the students is unknown.

...

output should look like this:

Name Surname class: D

Name2 Surname2 class: A

but mine output loos like this:

Name Class A

urname Class S

Name2 Class E

urname2 Class S ...

here is the code:

#include <iostream>
#include <fstream>
using namespace std;
 
int main() 
{
    ifstream file("students.txt");
    
    if (!file.is_open()) 
    {
        cout << "file can't be opened!" << endl;
        exit(-1);
    }

        char classs;
        string name, dummy;

    while(file >> classs >> name) 
    {
        
      cin.get(classs);
      getline(cin, dummy);
      getline(cin, name);
      
      cout << name << " " << "calass " << classs << endl;
    }
}






It looks like you've tried all kinds of things to make this work, including reading from cin in the middle of your loop that reads from file .. Very strange. I suggest you throw out the entire loop and try something simple as follows:

You just read one line at a time. For each line you read, you put that into a string stream and read the values out of that. To keep it even simpler, just read a string for everything, even if it's supposed to be just one character.

// Note: requires <sstream>

string line;
while(getline(file, line))
{
    istringstream iss(line);
    string cls, name, surname;
    if (iss >> cls >> name >> surname)
    {
        cout << name << " " << surname << " class: " << cls << endl;
    }
}

This does assume that there are always exactly two names, and it seems like that might not be the case for your input.

As an alternative, you could try reading the single character, then ignoring whitespace, and then read the entire rest of line:

char cls;
string fullname;
while (getline(file >> cls >> std::ws, fullname))
{
    cout << fullname << " class: " << cls << endl;
}

Note that the above is being a bit lazy, and as a result this might break if you encounter an empty line in your file. So, combining with the istringstream approach would be the way to go:

string line;
while (getline(file, line))
{
    istringstream iss(line);
    char cls;
    string fullname;
    if (iss >> cls >> std::ws >> fullname)
    {
        // Note you may also want to test cls is valid (e.g. isalpha(cls))
        cout << fullname << " class: " << cls << endl;
    }
}

In the end, if your input is line-based, then as a general preference you should read lines and then decide what to actually do with them.

You are using both getline() and >> for reading from the file stream, and you shouldn't be. Here is an example using just >> :

std::string cls, name, surname;
while(file >> cls >> name >> surname) 
{
    std::cout << name << " " << surname << " class: " << cls << std::endl;
}

I am assuming that each line of the file has exactly three elements - class, name and surname, as that is the example in the question. If that is not the case, then you'll really need to read the file's contents line by line using getline() and then parse each line using for example istringstream .

Also, you are using both file and cin and your data is only in the file, so you don't need to be using cin at all.

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