Home > Software design >  How to read from multiple lines in a file?
How to read from multiple lines in a file?

Time:12-17

I am learning C and am having a bit of a hard time with files. This is a little exercise that I am trying to do. The program is meant to read from a file and set it to its proper variables. The text file is as so:

Adara Starr 94
David Starr 91
Sophia Starr 94
Maria Starr 91
Danielle DeFino 94

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

const int MAXNAME = 20;

int main()
{
    ifstream inData;
    inData.open("grades.txt");

    char name[MAXNAME   1]; // holds student name 
    float average;          // holds student average

    inData.get(name, MAXNAME   1);

    while (inData)
    {
        inData >> average;
        cout << name << "has an average of " << average << endl;

        //I'm supposed to write something here
    }

    return 0;
}

When I try to run the code, only the first line is being read and displayed and then the program ends. More specifically, the output is

Adara Starr         has an average of 94
Adara Starr         has an average of 0

How do I read the next line from the txt file? I've also done while (inData >> average) in place of the inData condition but it also does the same thing minus the second "Adara Starr has an average of 0"

CodePudding user response:

You read only one name, then loop to read averages. That doesn't match the contents of the file.

Use getline to read lines, then use a stringstream to parse the lines:

#include <sstream>
#include <string>
#include <iostream>

int main()
{
    std::stringstream ss{ R"(Adara Starr 94
David Starr 91
Sophia Starr 94
Maria Starr 91
Danielle DeFino 94)"};

    std::string line;
    while (std::getline(ss,line)) {
        std::stringstream linestream{line};
        std::string first;
        std::string last;
        double avg;
        linestream >> first >> last >> avg;
        std::cout << first << " " << last << " " << avg << "\n";
    }   
}

CodePudding user response:

Hope it would help you a little bit, but I'd like to warn that since inner for loop checks only digits, you will loose your data if average will be consists of floating point numbers.

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

const int MAXNAME = 20;

int main()
{
    ifstream inData;
    inData.open("grades.txt");

    for(string line; getline(inData, line);) {
        // parse line
        // get number index
        size_t num_index = str.length() - 1;
        for(; num_index >= 0 && is_digit(str[num_index]); --num_index)
            ;

        string name = line.substr(0, num_index - 1); // skip space char

        if(name.length() > MAXNAME) 
            throw runtime_error("Name could not be more that "   MAXNAME   " length");

        float avarageStr = stof(line.substr(num_index   1));

        cout << name << "has an average of " << average << endl;

        //I'm supposed to write something here
    }

    return 0;
}

CodePudding user response:

I hope this helps:

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

const int MAXNAME = 20;

int main() {
    ifstream inData("input.txt");
    string str = "";

    while (!inData.eof()) {//use eof=END OF FILE
        //getline(inData, str); use to take the hole row

        /*can use string also
        string firstName;
        string lastName;
        string avg;*/

        char firstName[MAXNAME];
        char lastName[MAXNAME];
        float avg;

        //you can read from a file like you read from console(cin)
        inData >> firstName >> lastName >> avg;//split the row

        cout << firstName << " " << lastName << " " << avg<<"\n";
        
    }

    inData.close();
    return 0;
}

Output: Adara Starr 94

David Starr 91

Sophia Starr 94

Maria Starr 91

Danielle DeFino 94

  • Related