使用getline读取文本文件:行列与学生数据存入指针数组无输出问题
解决C++读取学生成绩文件的问题
我看了你的代码,发现几个关键问题导致程序完全没有输出,咱们一步步拆解问题,再给出修正后的实现:
你的代码里的核心问题
- 重复读取首行+错误复用istringstream:你用
while (inputFile.good())包裹首行读取逻辑,这会导致反复读取首行;而且第二个while循环里,你还在复用处理首行的accessFiles流——这个流已经读完首行数据了,根本读不到后续行的姓名信息,自然不会有输出。 - 变量初始化缺失:代码里没看到你初始化
i为0,如果i是随机值,会直接导致数组越界,程序可能崩溃或者无输出。 - 指针数组未正确初始化:如果
arrayOfStudentNames是string*或者char**类型,你需要提前根据读取到的rows分配足够的内存,否则无法存储学生姓名。
修正后的完整代码示例
假设你的文件格式是这样的(首行是行数、列数,后续每行是名、姓、成绩):
3 2 John Doe 90 Jane Smith 85 Bob Brown 95
对应的C++代码:
#include <iostream> #include <fstream> #include <sstream> #include <string> using namespace std; int main() { ifstream inputFile("students.txt"); if (!inputFile.is_open()) { cerr << "无法打开文件!" << endl; return 1; } string accessInputFilesInfo; int rows, cols; // 读取首行并解析行列数 if (getline(inputFile, accessInputFilesInfo)) { istringstream firstLineStream(accessInputFilesInfo); if (!(firstLineStream >> rows >> cols)) { cerr << "首行格式错误!" << endl; return 1; } } else { cerr << "文件为空!" << endl; return 1; } // 初始化存储学生姓名的指针数组(这里用string*更方便,避免手动管理char内存) string* arrayOfStudentNames = new string[rows]; // 如果是用char**的话,需要这样初始化: // char** arrayOfStudentNames = new char*[rows]; int i = 0; string firstName, lastName; int score; // 假设成绩是整数,可根据实际调整类型 // 循环读取后续每行数据 while (getline(inputFile, accessInputFilesInfo) && i < rows) { istringstream lineStream(accessInputFilesInfo); // 解析当前行的姓名和成绩 if (lineStream >> firstName >> lastName >> score) { string studentName = firstName + " " + lastName; arrayOfStudentNames[i] = studentName; // 如果是char**的话,需要分配内存并拷贝: // arrayOfStudentNames[i] = new char[studentName.size() + 1]; // strcpy(arrayOfStudentNames[i], studentName.c_str()); i++; } else { cerr << "第" << i+2 << "行格式错误!" << endl; } } // 输出测试,验证是否读取成功 cout << "读取到的学生姓名:" << endl; for (int j = 0; j < i; j++) { cout << arrayOfStudentNames[j] << endl; } // 释放内存 delete[] arrayOfStudentNames; inputFile.close(); return 0; }
关键改进点说明
- 首行只读取一次:用
if (getline(...))代替循环,确保只解析一次行列数,同时增加了错误判断(文件为空、首行格式错误)。 - 每行单独创建istringstream:每次读取一行后,用新的
istringstream解析当前行的内容,避免复用旧流导致的读取失败。 - 初始化指针数组:根据
rows分配足够的内存,用string*可以避免手动管理C风格字符串的内存,更安全便捷。 - 边界检查:循环里加上
i < rows,避免数组越界;同时对每行的解析结果做判断,跳过格式错误的行。 - 内存释放:最后记得释放指针数组的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user8628552
相关产品推荐
相关产品推荐

