0

This is the text file which is called grades.txt :

John   Sebastian    90  80   85  90     75 70  89 80 90       86 88 89 99 100  

Brown  Ford         40  60   80  85     60 90 100 80 90       83 81 89 97 90

I need to read all the data and put them in separate arrays. First 4 grades are exams , second are quizzes and third are homeworks.

#include <iostream>
#include <fstream>

using namespace std;

void letter_grade(string names[][2], int exams[][4], int quiz[][5], int homeworks[][5], float grades[2][2]);

int main() {

ifstream Openfile("grades.txt");


string names[2][2];
int exams[4][4];
int quiz[5][5];
int homeworks[5][5];

if(Openfile.is_open()){
for(int i = 0 ; i<2 ; i++){
    Openfile >> names[i][0];
}
    for(int j = 0 ; j<2; j++){
        Openfile >> names[j][1];
    }
}
    else{
    cout << "File is not open." << endl;
}
if(Openfile.is_open()){
    for(int x = 0 ; x<4 ; x++){
        for(int y = 0; y<4 ; y++){
            Openfile >> exams[x][y];
        }
    }
}


    return 0;
}

So arrays I've planned will be like this :

names[0][0] = John
names[1][0] = Sebastian 
names[0][1] = Brown
names[1][1] = Ford        

and so on. But I couldn't manage to do that , instead code keeps reading the exam results and writing them into the names array.

Then I will be calculating the grades of these students from arrays and save the result on a different file which I will do if I can read the data off the text file.

  • 1
    read in the file (and write into the arrays) row wise, not column wise. – Stephan Lechner Sep 06 '17 at 05:46
  • [Here](https://stackoverflow.com/questions/23047052/why-does-reading-a-record-struct-fields-from-stdistream-fail-and-how-can-i-fi)'s a number of suggestions how you can handle that. First of all provide a data structure for each record. – user0042 Sep 06 '17 at 06:16

1 Answers1

0

multi-dimension arrays don't carry semantic information for the individual component or member value. you have to do the translation between the meaning of data and the position in the array in your head. instead use proper data structure to make your code meaningful.

your specific example can be written like this:

// the record data
struct StudentScore {
    std::string firstname, lastname;
    int exams[4];
    int quizzes[5];
    int homeworks[5];
};
// parse the text, assuming data is well formatted
StudentScore parse_one_record (std::istream &is) {
    StudentScore score{};
    is >> score.firstname >> score.lastname;
    for (auto &exam: score.exams) is >> exam;
    for (auto &quiz: score.quizzes) is >> quiz;
    for (auto &homework: score.homeworks) is >> homework;
    // consume any trailing whitespaces including LF
    is >> std::ws;
    return score;
}

int main (int, char *[]) {
    auto file = std::ifstream("grades.txt");
    file >> std::ws;
    auto records = std::vector<StudentScore>{};
    // assume the file is well formatted.
    while (!file.eof()) {
        records.push_back(parse_one_record(file));
    }
    // now you can begin processing your data
}
书呆彭
  • 101
  • 4
  • Please, take a look at this: https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – Bob__ Sep 06 '17 at 08:23
  • that's right, my code doesn't handle exceptional cases properly, but it is intended to demonstrate the basic concept other than how to write industrial strength C++ code. as I already stated in the comments of the code, this code only deal with well formatted data. of course in production code, it can never be too defensive when it comes to parsing or any tasks that deal with untrusted data sources. – 书呆彭 Sep 06 '17 at 08:54