Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading from input file

Tags:

c++

I'm having trouble reading from an input file. The input file looks like this

Lionel Messi -10 43

Fernando Torres 9 -29

Cristiano Ronaldo 7 31

Wayne Rooney 10 37

Neymar 17 29

Andres Iniesta 8 32

Robin van Persie 19 20

Lionel Messi 10 43

Xavi Hernandez 6 36

Mesut Özil 10 38

Didier Drogba 10 35

Fernando Torres 9 29

Kaká 10 17

The problem is that I cant use the getline function because I want to store the name into a single variable to store into an array, and the first number into a variable and the second into another variable. I also tried to use the peek function but I have never learned that so I had no success with it. If anyone knows how to read until the end of the name and store it into a single variable that would be much appreciated.

This is what my code looks like when im reading from the input file

while(!fin.eof())
    {

     fin >> first >> last >> num >> point;

     if (num > 0 && point > 0)
     {
             list[i].firstname = first;
             list[i].lastname = last;
             list[i].number = num;
             list[i].points = point;
             i++;
     }
     else if (num < 0 || point < 0)
     {
             reject[j].firstname = first;
             reject[j].lastname = last;
             reject[j].number = num;
             reject[j].points = point;
             j++;
     }

    }

This works perfectly if the input has a first and a last name. I know the problem is on the fin >> first >> last >> num >> point;

but i am not exactly sure how to put first and last (and possibly middle) together

like image 301
kylekolossus Avatar asked Apr 24 '13 23:04

kylekolossus


2 Answers

You can use std::getline to extract the lines, the parse the line into a std::vector of space separated words. Then you know that words.size() - 2 of the words are part of the name. For example:

std::fstream in("in.txt");
std::string line;

// Extract each line from the file
while (std::getline(in, line)) {
  std::istringstream line_stream(line);

  // Now parse line_stream into a vector of words
  std::vector<std::string> words(std::istream_iterator<std::string>(line_stream),
                                 (std::istream_iterator<std::string>()));

  int name_word_count = words.size() - 2;
  if (name_word_count > 0) {
    // Concatenate the first name_word_count words into a name string
    // and parse the last two words as integers
  }
}
like image 147
Joseph Mansfield Avatar answered Oct 17 '22 03:10

Joseph Mansfield


It looks to me like you need to use getline, and then parse the line. One solution for parsing it might be to split the line just before the first digit, then trim the first half, and use it for the name, and parse the second half using an std::istringstream to read the two numbers. This will fail, of course, if someone has a digit as part of their name, but that seems to me to be a legitimate limitation. In other words, for each line, you'd do:

std::string::iterator first_digit
        = std::find_if( line.begin(), line.end(), IsDigit() );
if ( first_digit == line.end() ) {
    //  format error...
} else {
    name = trim( std::string( line.begin(), first_digit ) );
    std::istringstream parser( std::string( first_digit, line.end() ) );
    parser >> firstNumber >> secondNumber >> std::ws;
    if ( !parser || parser.get() != EOF ) {
        //  format error...
    } else {
        //  Do what ya gotta do.
    }
}
like image 26
James Kanze Avatar answered Oct 17 '22 03:10

James Kanze