0

I am having an issue with C++ structures. In my program below, I am trying to read from a file the number of questions to an exam, the answers to the exam, and the file of the student's answers to the exam. That all works, but when I try to put the student's info into an array for a structure, the variable id doesn't work for some reason. The compiler, which is Microsoft Visual Studio 2017 RC, says that "students->id[i]" has an error which says: "expression must have pointer to object type" and I don't know why. I marked where the issue is and took off the rest of the code, all I have is the function calculateGrade being used. I've worked on this for a while now and can't get anywhere without fixing this. Any help is appreciated!

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
struct studentInfo {
    int id;
    string firstName;
    string lastName;
    string exam;
};
double calculateGrade(struct studentInfo);
int main() {
    const int SIZE = 12;
    studentInfo students[SIZE];
    string fileName, key, studentFile;
    ifstream file, fileForStudents;
    int numOfQuestions, i = 0, id;

    cout << "Please enter a file name: ";
    cin >> fileName;

    file.open(fileName);
    if (!file.is_open()) {
        cout << "Could not open file";
    }

    file >> numOfQuestions >> key >> studentFile;

    fileForStudents.open(studentFile);
    if (!fileForStudents.is_open()) {
        cout << "Could not open file";
    }

    while (!fileForStudents.eof()) {

        fileForStudents >> id >> students->firstName[i] >> students->lastName[i] >> students->exam[i];

        students->id[i] = id; //issue is here

        i++;
    }

    calculateGrade(students[SIZE]);


    return 0;
}
  • Having constants in C++ in UPPERCASE is anti-pattern. – Slava Dec 08 '16 at 21:30
  • 2
    [`while (!file.eof())` is wrong](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Barmar Dec 08 '16 at 21:31

2 Answers2

2

You just put index wrong place - it should be students[i].firstName instead of students->firstName[i] and so on, as students is the array.

Also this line is incorrect:

calculateGrade(students[SIZE]);

it may compile, but you would have UB for out of bounds access. If you need to pass whole array then pass a pointer to the first element and size, but better use std::vector or std::array and pass it by reference.

So for additional question as why such code:

 students->firstName[i]

compiles, first students is a C style array, which can implicitly decay to a pointer to the first element, so students->firstName is equal to students[0].firstName and then students->firstName[i] is equal to students[0].firstName[i] would access i-th symbol from the string.

So there is another reason to use std::vector - your expression students->firstName[i] would not compile either not providing false expression that such code is correct.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • @Barmar thx, fixed, there are too many problems to catch all of then at once – Slava Dec 08 '16 at 21:36
  • Thank you for your help, I must have forgotten to put the index there when I was rewriting the code, I tested it in a different way where I got the text into a variable and then into the array, but I then later moved it so that it went immediately into the array, and just put the index in the wrong place. Do you know why only the id part of the array was the only one giving me an error? – FreckledTerror97 Dec 08 '16 at 21:37
  • @FreckledTerror97 Because you can index a string, it references the character in the string at that position. – Barmar Dec 08 '16 at 21:38
  • @FreckledTerror97 becasue `std::string` has `operator[]` as well, that gives you one symbol, but `int` is not an array or object. – Slava Dec 08 '16 at 21:39
  • @Slava What data type would the vector be? – FreckledTerror97 Dec 08 '16 at 21:43
  • @FreckledTerror97 `std::vector`, get a good textbook on C++ it should explain how to use it. But if you in the beginning of learning it is ok to use C style array, just keep in mind in C++ there is a better way. – Slava Dec 08 '16 at 21:49
2

students->id is just a single int, it's not an array, so you can't use students->id[i].

The array is students, so it should be students[i].id. You don't use -> because students is an array of structures, not an array of pointers.

Barmar
  • 741,623
  • 53
  • 500
  • 612