0

I am trying to read each line of a text file in C++. I have it working for the first line in a text file, but how do I read the others? Also, I am a C++ super noob, please don't roast me.

Code:

void Grade::readInput()
{
    ifstream infile("Grades.txt");

    if (infile.good())
    {
        string sLine;
        getline(infile, sLine);
        cout << "This is the val " << sLine << endl;
    }

    infile.close();
}

This is the output I want:

This is the val 12

This is the val 17

This is the val 1

This is the val 29

Algirdas Preidžius
  • 1,769
  • 3
  • 14
  • 17
EatSleepCode
  • 452
  • 7
  • 21
  • 4
    Use a `while` loop instead of `if`. – 001 Sep 18 '19 at 19:44
  • 2
    1) "_I have it working for the first line in a text file, but how do I read the others?_" Did you try using a loop? Consider learning from a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). 2) Why is this question tagged with [tag:c], if it's, obviously, not C? – Algirdas Preidžius Sep 18 '19 at 19:44
  • Super noob is ranking up. Thank you Johnny Mopp – EatSleepCode Sep 18 '19 at 19:46

2 Answers2

1

I'll give you some hints - this is probably more like CodeReview.SE now...

I would recommend

  • separating the reading from printing
  • treating the grades as numbers (e.g. int or double) so you can actually work with them, and have some validation that you're not reading non-sense
  • Use idiomatic loops, don't just if (infile.good()) - e.g. you can't tell whether you've reached end-of-file before you try to read

Fixing up the interface, I'd suggest something like this

struct Grade {
    void readInput(std::string fname);

    void print(std::ostream& os = std::cout) const;
  private:
    static constexpr auto max_line_length = std::numeric_limits<ssize_t>::max();
    std::vector<int> grades;
};

Note that readInput reads into grades without printing anything. Note also that it takes the name of the file to read as the argument, instead of hardcoding some filename.

int main() {
    Grade grading;

    grading.readInput("grades.txt");
    grading.print();
}

This would be the main program.

The simplified/extended version of readGrades could be:

void Grade::readInput(std::string fname) {
    std::ifstream infile(fname);

    infile.ignore(max_line_length, '\n'); // ignore the first line

    int grade = 0;

    while (infile >> grade) {
        grades.push_back(grade);
        infile.ignore(max_line_length, '\n'); // ignore rest eating newline
    }
}

Note how we ignore lines or parts thereof that we are not interested in. For extra control consider disabling white-space skipping:

 infile >> std::nowskipws;

The print function could be a simple:

void Grade::print(std::ostream& os) const {
    os << "Grades:";
    for (int g : grades) {
        os << " " << g;
    }
    os << std::endl;
}

Full Demo

Live On Coliru

#include <fstream>
#include <string>
#include <vector>
#include <iostream>

struct Grade {
    void readInput(std::string fname);

    void print(std::ostream& os = std::cout) const;
  private:
    static constexpr auto max_line_length = std::numeric_limits<ssize_t>::max();
    std::vector<int> grades;
};

int main() {
    Grade grading;

    grading.readInput("grades.txt");
    grading.print();
}

void Grade::readInput(std::string fname) {
    std::ifstream infile(fname);

    infile.ignore(max_line_length, '\n'); // ignore the first line

    int grade = 0;

    while (infile >> grade) {
        grades.push_back(grade);
        infile.ignore(max_line_length, '\n'); // ignore rest eating newline
    }
}

void Grade::print(std::ostream& os) const {
    os << "Grades:";
    for (int g : grades) {
        os << " " << g;
    }
    os << std::endl;
}

Prints

Grades: 12 17 1 29

Given grades.txt:

Ignore the first line
12
17
1
29
sehe
  • 374,641
  • 47
  • 450
  • 633
0

A simple version:

std::string line1;
std::string line2;
std::string line3;
std::string line4;
std::getline(infile, line1);
std::getline(infile, line2);
std::getline(infile, line3);
std::getline(infile, line4);

With a loop:

static const unsigned int LINES_TO_READ = 3;
std::string line1_ignored;
std::getline(infile, line1_ignored);
for (unsigned int i = 0; (i < LINES_TO_READ); ++i)
{
   std::string text_line;
   if (std::getline(infile, text_line))
   {
      std::cout << text_line << std::endl;
   }
   else
   {
       break;
   }
}

Both versions read the first line. Ignore the contents in the variable if you wish.

The simple method reads each text line, into separate variables.

The second reads text lines using a known-quantity loop.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154