Вызывается исключение при вызове функции atoi(strtok(NULL,","));

написал код,все хорошо,но вылазит исключение,когда я использую функцию atoi(strtok(NULL,",")).Суть задачи заключается во внесении данных о студенте в файл,и определение учеников у кого средний балл по 3 предметам меньше 4 и вывод всего этого на консоль,маленький косяк,не могу разобраться

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<ctime>
#include<fstream>
#include<cstdlib>
using namespace std;
int main() {
    
    
    ofstream file("task.txt");
    char name[12];
    int group = 0, mark1 = 0, mark2 = 0, mark3 = 0, n = 0;
    cout << "Input number of students: ";
    cin >> n;

 
    for (int i=0; i < n; i++) {
        cout << "Student " << i+1 << ":" << endl;
        cout << "Name: ";
        cin >> name;
        cout << "Group: ";
        cin >> group;
        cout << "Marks:" << endl;
        cin >> mark1 >> mark2 >> mark3;
        file << name << ";" << group << ";" << mark1 << ";" << mark2 << ";" << mark3 << "."<<endl;
    }
    file.close();
    
    ifstream file1("task.txt");
    char student[25];
    char* surname;
    int i = 1;
    bool flag = 0;
  cout << "Students who have an average less than 4:\n";
    while (file1.getline(student, 25, '.')) {
        surname = strtok(student, ";");
        group = atoi(strtok(NULL, ";"));
        mark1 = atoi(strtok(NULL, ";"));
        mark2 = atoi(strtok(NULL, ";"));
        mark3 = atoi(strtok(NULL, ";"));
        int sum = mark1 + mark2 + mark3;
        if (sum<12) {
            cout << "Student " << i << ":" << endl;
            cout << "Name: " << surname << endl;
            cout << "Group: " << group << endl;
            cout << "Marks: " << mark1 << "; " << mark2 << "; " << mark3 << "." << endl;
            flag = 1;
            cout << endl;
        }
        i++;
    }
    if (!flag) cout << "There are no students who have an average less than 4";
    file1.close();
    return 0;
}

Ответы (1 шт):

Автор решения: Павел Ериков

Ошибка заключается в том, что если например у вас 2 студента, то цикл пройдет 3 раза. Потому что вы считываете строку по разделителю '.', но в конце файла стоит '\n' вот и получается, что вы на 3 итерации в surname записываете '\n', а дальше идут ошибки одни.

Так же недочет, то что например у второго студента в начале фамилии будет стоять '\n'.

И чтобы это исправить просто не записывайте в файл символ новой строки :)

Ну или вам так нужен переход на новую строчку, то под конец итерации (после i++) можете добавить такую строчку:

file1.seekg(2, ios::cur);

Эта строчка перемещает указатель потока на 2 байта вперед, а ios::cur означает - относительно текущей позиции. А 2 байта потому, что символ новой строки столько занимает.

→ Ссылка