строки с массивами - PullRequest
       12

строки с массивами

1 голос
/ 12 октября 2011

привет, у меня есть такая структура:

struct Student
{
string name,lettergrade;
int stdnumber,*examgrades;
double  avarege;
};

Мне нужно составить программу, которая рассчитывает средние и буквенные оценки ученика.

Я должен использовать эту функцию:

void getdata();
double calcgrades();
void show();
void erase();

Я должен спросить пользователя об общем количестве студентов и общем количестве экзаменов. тогда я должен выделить необходимые места в памяти. (с динамическим размещением)

Экран вывода должен быть таким:

Enter the number of students: 2
Enter the number of exams: 2
1. student's name: michael
1. student's school number: 5000
1. student's 1. exam grade: 50
1. student's 2. exam grade: 40
The avarege of this student is: 45 Letter grade: F
2. student's name: [b]mary[/b]
2. student's school number: 6000
2. student's 1. exam grade: 70
2. student's 2. exam grade: 80
The avarege of this student is: 75 Letter grade: B

Моя проблема в том, что я не могу выделить его для строковых переменных, таких как имя ученика и буквенная оценка ... (в функции getdata)

Буквенные оценки: A: 85–100, B: 75–84, C: 65–74, D: 50–64, F: 0–49, более 100 баллов.

Может кто-нибудь иметь представление об этой проблеме?

EDIT:

void getdata()
{
    int i,j;
    i=0;j=0;
    int stdnumber;
    int examnumber;
    cout<<"How many students..."<<endl;
    cin>>stdnumber;
    Student k[stdnumber];
    cout<<"How many exams...."<<endl;
    cin>>examnumber;
    for (i=0;i<stdnumber;i++)
    {
        cout<<i+1<<". student's name: "<<endl;
        cin>>k[i].name;
        cout<<i+1<<". student's school number: "<<endl;
        cin>>k[i].stdnumber;
        for (j=0;j<examnumber;j++)
        {
            cout<<i+1<<". student's "<<j+1<<". exam grade: "<<endl;
            cin>>k[i]->examgrades; //The error is here: base operand of '->' has non-pointer type 'Student'|

        }
    }

}

То, что я пытаюсь вам сказать, это моя проблема с указателями. Я не знаю, как мне выделить достаточно места в памяти для экзаменационных оценок?

Ответы [ 2 ]

2 голосов
/ 12 октября 2011

Вам не нужно выделять какие-либо string (хотя, если бы вы это сделали, проблем не возникало).Вы должны выделить Student.В C ++ нормальный способ выделения массива Student будет выглядеть следующим образом:

std::vector <Student> students( studentCount );

Аналогично, обычный способ выделения массива int будет:

std::vector <int> examgrades( examCount );
* 1010.* Для этого потребуется изменить структуру Student на что-то вроде:
struct Student
{
    std::string         name;
    std::string         letterGrade;
    int                 studentNumber;
    std::vector <int>   examGrades;
    double              average;

    Student( int examCount ) : examGrades( examCount ) {}
};

Если вы используете указатель для Student::examGrades, невозможно правильно написать код на C ++, не предоставив оба конструктораи деструктор для Student.Если вы сделаете вышеизложенное, после того, как вы введете количество студентов и количество экзаменов, все, что вам нужно сделать, это:

std::vector <Student> students( studentCount, Student( examCount ) );

, и все необходимое будет распределено.Или же вы инициализируете вектор пустым и перебираете ввод, используя push_back для добавления полностью инициализированных учеников.(На самом деле это гораздо лучшее решение, поскольку оно препятствует тому, чтобы любой студент когда-либо существовал без правильной инициализации.)

Если ваш профессор пытается преподавать какое-то другое решение, используя указатели (в этом указатели не должны бытьпрограммы), тогда я бы порекомендовал вам сменить профессора (и, если возможно, уволить этого за некомпетентность).Однако до тех пор вы всегда можете сделать

Student* students = new Student[studentCount];
for ( int i = 0; i != studentCount; ++ i )
    students[i].examGrades = new int[examCount];

. Конечно, getData придется возвращать какой-то struct, поскольку он должен возвращать указатель на Student s,плюс studentCount и examCount.И где-то вам придется написать код, чтобы удалить всю эту память.(И если вы действительно хотите сделать это правильно, вам придется обернуть большую часть кода во множество try ... catch блоков, чтобы правильно освободить память, если есть исключение. std::vector заботится о выделении, удаляети вся обработка исключений для вас.)

2 голосов
/ 12 октября 2011

В вашем коде k - это массив Student, а не массив Student*.Поэтому вам нужно использовать . вместо ->.Вот почему вы получаете эту ошибку.Другая проблема с этим кодом заключается в том, что вы используете непостоянное значение для размера массива, что недопустимо в C ++.

Для динамического размещения самым простым решением будет использование std::vector.Это обеспечивает как распределение, так и освобождение, без особой осторожности.

Учитывая, что это домашняя работа, если по какой-то причине вам не разрешено использовать std::vector, вам нужно будет использовать new[] и delete[].

Если по какой-то невероятно глупой причине вы не можете использовать new[] и delete[], вам нужно использовать malloc и free.

...