VS2019环境下C++同样的函数读取同样的文件为什么会有差异?

       这几天在搞一个作业,大体内容是将学生的一些信息、成绩写入到文件中,然后再把他们读取出来按照成绩采用不同方式的排序(冒泡、选择、插入、快速等)。最后出现了一个问题,是在Switch语句中,每次都会调用同一个读取文件的函数,在进行不同的排序后,堆排序的结果显示出某一个结构体数组没有初始化的结果

上代码:
 

// 功能函数实现.cpp
#include"head.hpp"    // 头文件中定义了各个函数以及头文件

void Show_Menu() {

	cout << "*************************" << endl;
	cout << "      1、录入学生基本信息" << endl;
	cout << "      2、直接插入排序" << endl;
	cout << "      3、冒泡排序" << endl;
	cout << "      4、快速排序" << endl;
	cout << "      5、简单选择排序" << endl;
	cout << "      6、堆排序" << endl;
	cout << "      7、2-路归并排序" << endl;
	cout << "      8、输出学生信息" << endl;
	cout << "      0、退出" << endl;
	cout << "*************************" << endl;

}

void File_Read(Student stu[]) {

	ifstream ifs;
	ifs.open("StudentData.txt", ios::in);

	int i = 1;
	while (ifs >> stu[i].Id && ifs >> stu[i].Name && ifs >> stu[i].Score)
		++i;
	ifs.close();

}

// 直接插入排序
void Sort_Insert(Student stu[], int num) {

	int j;
	for (int i = 2; i <= num; ++i) {
		if (stu[i].Score > stu[i - 1].Score) {
			stu[0] = stu[i];
			stu[i] = stu[i - 1];
			for (j = i - 2; stu[0].Score > stu[j].Score; --j)
				stu[j + 1] = stu[j];
			stu[j + 1] = stu[0];
		}
	}

	Input_Position(stu, num);
}

// 冒泡排序
void Sort_Bubble(Student stu[], int num) {

	Student temp;
	for (int i = 1; i <= num - 1; ++i)
		for (int j = i + 1; j <= num; ++j)
			if (stu[i].Score < stu[j].Score) {
				temp = stu[i];
				stu[i] = stu[j];
				stu[j] = temp;
			}
	
	Input_Position(stu, num);
}

// 获取分割的位置
int getStandard(Student stu[], int low, int high) {

	int i = low - 1;
	int j = high;
	int key = stu[j].Score;

	while (true) {

		while (stu[++i].Score > key);
		while (stu[--j].Score < key);

		if (i < j)
			swap(stu[i], stu[j]);
		else
			break;

	}
	swap(stu[i], stu[high]);

	return i;
}

// 快速排序
void Sort_Quick(Student stu[], int low, int high) {

	if (low < high) {
		int mid = getStandard(stu, low, high);
		Sort_Quick(stu, low, mid - 1);
		Sort_Quick(stu, mid + 1, high);
	}

}

// 简单选择排序
void Sort_Choose(Student stu[], int num) {

	int flag;
	for (int i = 1; i <= num - 1; ++i) {
		flag = i;
		for (int j = i + 1; j <= num; ++j)
			if (stu[flag].Score < stu[j].Score)
				flag = j;

		if (flag != i)
			swap(stu[flag], stu[i]);
	}

	Input_Position(stu, num);
}

/*	堆排序
	堆排序的要点:
		下标为i的结点,父节点下标为(i-1)/2
		下标为i的结点,左孩子下标为i*2+1
		下标为i的结点,右孩子下标为i*2+2
*/
// 数据降序排序,需要使用小根堆
// 以小根堆为基础,维护堆的性质
void Defend_Heapify(Student stu[], int n, int i) {

	int min = i;	// 假设根节点为最大
	int l_son = i * 2 + 1;
	int r_son = i * 2 + 2;

	if (l_son < n && stu[l_son].Score > stu[min].Score)
		min = l_son;
	if (r_son < n && stu[r_son].Score > stu[min].Score)
		min = r_son;
	
	if (min != i) {
		swap(stu[min], stu[i]);
		Defend_Heapify(stu, n, min);
	}

}

// 堆排序的入口
void Sort_Heap(Student stu[], int n){

	// 建立堆
	for (int i = n / 2 - 1; i > 0; --i)
		Defend_Heapify(stu, n, i);

	// 进行排序
	for (int j = n - 1; j > 0; --j) {
		swap(stu[j], stu[0]);
		Defend_Heapify(stu, j, 1);
	}

	Input_Position(stu, n);
}

// 归并排序中用于划分区域的函数
void Merge_Algorithm(Student stu[], Student arr[], int left, int right) {

	// 区域中不止一个元素
	if (left < right) {
		// 划分中间点
		int mid = (left + right) / 2;
		// 划分左半区域
		Merge_Algorithm(stu, arr, left, mid);
		// 划分右半区域
		Merge_Algorithm(stu, arr, mid + 1, right);
		// 合并
		Merge_Arr(stu, arr, left, mid, right);
	}

}

// 归并排序中用于合并的函数
void Merge_Arr(Student stu[], Student arr[], int left, int mid, int right) {

	int l_pos = left;		// 左半区第一个未排序的元素
	int r_pos = mid + 1;		// 右半区第一个未排序的元素
	int pos = left;		// 临时数组下标

	while (l_pos <= mid && r_pos <= right) {

		if (stu[l_pos].Score > stu[r_pos].Score) {
			arr[pos] = stu[l_pos];
			++pos;
			++l_pos;
		}
		else {
			arr[pos] = stu[r_pos];
			++pos;
			++r_pos;
		}
	}

	// 合并左半区域
	for (; l_pos < mid; ++pos, ++l_pos) 
		arr[pos] = stu[l_pos];
	// 合并右半区
	for (; r_pos < right; ++pos, ++r_pos)
		arr[pos] = stu[r_pos];

	// 临时数组的元素赋给原数组
	while (left < right) {
		stu[left] = arr[left];
		++left;
	}

}

// 归并排序入口
void Sort_Merge(Student stu[], int n) {

	Student* tempArr = new Student[n];
	if (tempArr) {
		for (int i = 0; i < n; ++i)
			tempArr[i].Name = "";
		Merge_Algorithm(stu, tempArr, 1, n);
		delete[] tempArr;
	}
	else {
		cout << "error: failed to allocate memory" << endl;
	}

	Input_Position(stu, n);
}


void Swap(Student& s1, Student& s2) {

	Student temp = s1;
	s1 = s2;
	s2 = temp;

}

// 将学生的名次录入
void Input_Position(Student stu[], int num) {

	int j = 1;
	for (int i = 1; i < num; ++i)
		if (stu[i].Score != stu[i + 1].Score) {
			stu[i].Pos = j;
			++j;
			stu[i + 1].Pos = j;
		}
		else {
			stu[i].Pos = j;
			stu[i + 1].Pos = j;
		}

}

void Display_Information(Student stu[], int num) {

	cout << "名次\t 学号\t 姓名\t 成绩" << endl;
	for (int i = 1; i <= num; ++i)
		cout << stu[i].Pos << "\t" << stu[i].Id << "\t" << stu[i].Name << "\t" << stu[i].Score << endl;
	cout << endl;
}

// main.cpp
#include"head.hpp"
using namespace std;

int num = 0;

void Init_StudentInformation(Student stu[]) {

	cout << "本次录入信息的学生个数:";
	int after;
	cin >> after;
	num += after;
	
	int id, score;
	string name;
	ofstream ofs;
	ofs.open("StudentData.txt", ios::app);
	if (!ofs.is_open()) {
		cout << "Error: Open file failed." << endl;
		exit(-1);
	}

	for (int i = 1; i <= after; ++i) {
		cout << "第" << i << "位学生的学号:";
		cin >> id;
		cout << "第" << i << "位学生的姓名:";
		cin >> name;
		cout << "第" << i << "位学生的分数:";
		cin >> score;
		ofs << id << "\t" << name << "\t" << score << endl;
	}

	ofs.close();
}


int main() {

	Student* stu = new Student[100];
	int choice;
	ofstream ofs;
	ofs.open("StudentData.txt", ios::trunc);
	ofs.close();

	while (true) {

		Show_Menu();
		cin >> choice;
		switch (choice) {

		case 1:Init_StudentInformation(stu); cout << "Get Information Successfully." << endl;
			system("pause"); system("cls"); break;
		case 2: File_Read(stu); Sort_Insert(stu, num); cout << "Insert Sort Successfully." << endl;
			system("pause"); system("cls"); break;
		case 3: File_Read(stu); Sort_Bubble(stu, num); cout << "Bubble Sort Successfully." << endl;
			system("pause"); system("cls"); break;
		case 4: File_Read(stu); Sort_Quick(stu, 1, num); Input_Position(stu, num); cout << "Quick Sort Successfully." << endl;
			system("pause"); system("cls"); break;
		case 5: File_Read(stu); Sort_Choose(stu, num); cout << "Choose Sort Successfully." << endl;
			system("pause"); system("cls"); break;
		case 6: File_Read(stu); Sort_Heap(stu, num); cout << "Heapify Sort Successfully." << endl;
			system("pause"); system("cls"); break;
		case 7: File_Read(stu); Sort_Merge(stu, num); cout << "Merge Sort Successfully." << endl;
			system("pause"); system("cls"); break;
		case 8: cout << "Students' Information:" <<endl; Display_Information(stu, num);
			system("pause"); system("cls"); break;
		case 0: cout << "System Exit." << endl; return 0;
		default: cout << "Error: Input illegal. Please re-enter." << endl;

		}

	}

	return 0;
}

在其他选项中,输出的结果表明结构体数组中所输出的元素是有数据的,但是如果录入数据后先选择6(堆排序),就会有一个元素没有被赋初值

如下:

很明显第二个数据显示出的结果表明没有被初始化。

求帮助

很明显,读取行的时候发生了异常。
可以Debug到文件路径下
查看文件如何被读取。
while (ifs >> stu[i].Id && ifs >> stu[i].Name && ifs >> stu[i].Score)
++i;