-2

I realize there are similar questions to this however, those solutions seem to only work if a group of data is on the same line.

I have some data structured in text file like so:

<string student name>
<string course>
<float mark>
...

Every 3 lines is a new student, with a total of 6 students. My code works until it gets to the part where it assigns a mark, which I need to read in as a float, everything else is a string.

I;ve found that getline() won't do this for me, wondering what is the best way to work with mixed types from a text file?

#include <iomanip>
#include <ios>
#include <iostream>
#include <iterator>
#include <list>
#include <fstream>

struct Student {
    std::string name;
    std::string course;
    std::string grade;
    float mark;
};

int main() {

    Student students [6];
    std::string filename = "data.txt";
    std::ifstream file(filename);

    int i = 0;
    
    while(getline(file, students[i].name))
    {
        getline(file, students[i].course);
        getline(file, students[i].mark);
        
        if (students[i].mark > 89.5) {
            students[i].grade = "HD";
        } else {
            students[i].grade = "PASS";
        }
        
        ++i;
    }
    
    return 0;
}

Ari
  • 5,301
  • 8
  • 46
  • 120
  • what would be the content of data.txt? – OznOg Mar 21 '21 at 08:54
  • 1
    The [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) function reads *strings*. You can use `std::getline` to read lines into strings, and for the non-string values convert the string to the correct type (for example with [`std::stof`](https://en.cppreference.com/w/cpp/string/basic_string/stof)). – Some programmer dude Mar 21 '21 at 08:55
  • 1
    There are hundereds/thousands of examples on the web, especially things like Stack Overflow, or even just CppReference. You should be able to find your answer by yourself... – JHBonarius Mar 21 '21 at 08:57
  • @OznOg With the example above, line 1 is a persons name `JohnSmith`, line 2 is a course `math101`, line 3 is a mark `80.5`. Based on the mark I'd like to then determine the grade, example `if mark > 90 then garde = "HD" else "PASS"`. Once I do 3 `getline()`'s I then increment and move to the next student in the array. – Ari Mar 21 '21 at 09:01
  • Does this answer your question? [How can I ignore the "end of line" or "new line" character when reading text files word by word?](https://stackoverflow.com/questions/28259141/how-can-i-ignore-the-end-of-line-or-new-line-character-when-reading-text-fil) – Zoe Mar 21 '21 at 09:24
  • The same thing applies to reading lines of floats, meaning you can entirely skip `getline()` and just use `file >> students[i].mark; file.ignore();` – Zoe Mar 21 '21 at 09:26

1 Answers1

0

I had the requirement to get the data line by line, assuming every three lines was a new student. My next requirement was that the third line would be a float but getline() reads in as a string.

My solution was to just create a temporary variable to take the string and then convert it to a float on the fly.

#include <iomanip>
#include <ios>
#include <iostream>
#include <iterator>
#include <list>
#include <fstream>

struct Student {
    std::string name;
    std::string course;
    std::string grade;
    float mark;
};

int main() {

    Student students [6];
    std::string filename = "data.txt";
    std::ifstream file(filename);

    int i = 0;
    
    while(getline(file, students[i].name))
    {
        getline(file, students[i].course);

        string mark; // <-- to hold the string
        getline(file, mark);
        students[i].mark = std::stof(mark);
        
        if (students[i].mark > 89.5) {
            students[i].grade = "HD";
        } else {
            students[i].grade = "PASS";
        }
        
        ++i;
    }
    
    return 0;
}
``
Ari
  • 5,301
  • 8
  • 46
  • 120