0

So, the purpose of this program is to input data from a .txt file that has a long list of student IDs and three grades, and output this data into another .txt file, but with the IDs and the averaged grades. I am a bit stumped about how to make my program read the next line after it reads one line. Right now how the code is it just repeatedly prints the first line.

int main()

{

int id;
int score1;
int score2;
int score3;
ofstream output;
ifstream input;

int grade = 0.3 * score1 + 0.3 * score2 + 0.4 * score3;

  char letgrade;

if (grade >= 90.0)
char letgrade = 65;
else if (grade >= 80.0)
char letgrade = 66;
else if (grade >= 70.0)
char letgrade = 67;
else if (grade >= 60.0)
char letgrade = 68;
else char letgrade = 69;

output.open("studentGrade.txt");

do 
{

input.open("StudentInfo.txt");

input >> id >> score1 >> score2 >> score3;

output << id << " " << letgrade << endl;

input.close();

}

while (!input.eof());

output.close();

return 0;

 }

From what I understand, the getline function comes in handy here. It's just I need help regarding how to use it.

  • 1
    Well, yes, because you repeatedly open and close the file. – Martin James Apr 06 '20 at 00:50
  • That's not very helpful. – Jeffrey Golladay Apr 06 '20 at 00:51
  • 2
    TBH, the whole flow of your code makes no sense. For instance, you calculate grade from the scores before the scores are read in:( – Martin James Apr 06 '20 at 00:52
  • How do you use getline to read another line? This compiles BTW. – Jeffrey Golladay Apr 06 '20 at 00:53
  • 1
    Yes, I'm sure it does, it just won't do what you want. Open the file, then run the loop, then close the file, as clearly hinted at above in the 'not very helpful' comment. – Martin James Apr 06 '20 at 00:57
  • 2
    ... and put the calc of grade and letgrade inside the loop. C++ is not Excel! – Martin James Apr 06 '20 at 00:59
  • 1
    You should master simpler tasks such as reading in a single number, doing calculations with it, and then outputting it before you attempt to read from a file or to repeated calculations. You need to understand variables in C++ first, since you're trying to do the calculations before you read in the numbers which makes no sense. – eesiraed Apr 06 '20 at 03:34

2 Answers2

2

You are repeatedly reopening the file anew in input.open("StudentInfo.txt");

Your do {} while loop should be something more like the following (although you need to be careful with while (!stream.eof) {}):

input.open("StudentInfo.txt");
while (!input.eof()) {
  input >> ...;
  output << ... << endl;
}

The code posted has other issues a teacher would likely characterize as deficiencies: unorganized procedures, bloated predicate (if expression), failure to adhere to a recognizable variable and coding style - but nothing that a quick review of material presented in lecture or section notes on files, loops and a quick read of a well-regarded C++ style guide won't fix.

C++ is a tough language and countless veterans have "blown their feet off" in spite of an excellent command of the language. As a novice, you should expect that answers to questions (such as this one) to require a 30-45 minutes of additional research to define terms, place it in a wider context or develop intuition for the machinery.

zetavolt
  • 2,989
  • 1
  • 23
  • 33
  • Is it ok if I open the output file before I write something like what you said? In other words, can I do output.open("studentGrades.txt") before opening the input file and writing a while loop? – Jeffrey Golladay Apr 06 '20 at 00:57
  • 1
    Yep! In fact, "output" and "input" could be thought of as totally separate "files" (it's just that one can only be written to and one can only be read by your program) – zetavolt Apr 06 '20 at 01:02
  • Awesome, yes I just added this. This is much better now, but the main issue I have is that when the while loop is 'looping' the outputted data is staying on one line. I need it to go to a new line each iteration. Does getline have something to do with this? – Jeffrey Golladay Apr 06 '20 at 01:06
  • The truth is, I've been trying to do this all day long and I think I probably had more sensible code earlier in the day. The main thing that is stumping me is going to a new line. – Jeffrey Golladay Apr 06 '20 at 01:11
  • When you are inputting data from you std::ifstream object, newlines can be ignored, but when you are outputting data it will write to the file exactly in the same way that it would output to your console -- so if you need it moved to a new line, you need to output a newline character. – Shaavin Apr 06 '20 at 01:12
  • Ok.. Why doesn't endl; do that? I've never had trouble going to a new line when outputting to the console. – Jeffrey Golladay Apr 06 '20 at 01:14
  • 1
    You probably want to avoid this pattern: `while (!input.eof()) {` [https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – drescherjm Apr 06 '20 at 01:19
  • 1
    It sounds like using `std::endl` when outputting to a file and displaying properly is platform dependent (see [this](https://stackoverflow.com/questions/9705923/c-ofstream-line-break) for more explanation). Instead, I would recommend using [these escape characters](https://stackoverflow.com/questions/10220401/rules-for-c-string-literals-escape-character). – Shaavin Apr 06 '20 at 01:20
  • I'm not sure how I am supposed to use \n. Why would not endl work? I always use it. – Jeffrey Golladay Apr 06 '20 at 01:30
  • I simply need to know how in the world the *next* data is outputted in the *next* line. – Jeffrey Golladay Apr 06 '20 at 01:31
0

minimal working version, lots of comments.

#include <fstream>
#include <iostream>

// this here's a function. it's a bit of code that accepts 3 parameters,
// does stuff with them, prints a message, then returns a value.
int computeGradeAverage(int a, int b, int c)
    {
    int avg =  ( a + b + c ) / 3;
    std::cout << "computed average of " << a << ", " << b << ", " << c << ", is " << avg << std::endl;
    return avg;
    }

// the main function. typically programs have many functions, and the C/C++
// languages (and java etc etc) require a single 'main' function to start the program at
// (it can be up top, or at bottom of file, or in the middle; doesn't matter).
int main()
    {

    // a) allocate named variable of given types to hold values.
    int id;
    int score1;
    int score2;
    int score3;
    int gradeaverage;
    std::ofstream output;
    std::ifstream input;

    // b) open input and output files
    input.open("StudentInfo.txt");
    output.open("studentGrade.txt");

    // c) loop over each line of input file
    do
        {
        // c.i) read data (one line) in
        input >> id >> score1 >> score2 >> score3;

        // c.ii) do calculation on input data
        gradeaverage = computeGradeAverage(score1, score2, score3);

        // c.iii) write data out
        output << id << " " << gradeaverage << std::endl;
        }

    // d) stop looping if we have reached the end of the input file (eof = end of file)
    // ... 'input' is the file object; input.eof() is call of one of its member function s
    // ... the 'eof()' function will return true (if at end) or false (if there's more data).
    // ... "while(!thing)" means "while NOT thing" .. so the 'while ( ! input.eof()  )' means:
    //  ..  do { "the things" } while " input file not finished "
    while (!input.eof());
    // There are several ways of doing this, like while(!eof) { .. } and others.

    // e) close the files. while it'll work without doing this, it's a very important
    // habit to put away things after use; deallocate memory, close files, commit transactions,
    // free (as in liberate, not beer) any acquired resources, etc etc.
    input.close();
    output.close();

    // f) return a value to the caller. In this case, the caller is the operating system,
    // and at least with unixy programs, '0' means 'okay', and other numbers would mean
    // some error occurred. For example, the 'g++' compiler returns 1, on any error.
    return 0;
    }
jmullee
  • 390
  • 3
  • 6