为何读取文件填充数组时首轮正常,循环后续执行失败?
问题分析与解决方案
你遇到的核心问题是输入流的换行符残留,以及getline和>>混用导致的读取错位,另外代码里还有几处逻辑小问题,我来一步步拆解:
1. 为什么第一次读取正常,后续失败?
当你用dataFile >> consolePrices[i]读取价格时,这个操作会读取数字,但会把价格后面的换行符留在输入流中。下一次调用getline(dataFile, consoleNames[i])时,它会直接读取这个空的换行符,导致consoleNames[i]变成空字符串;接着再读取价格时,因为输入流里没有有效数字,consolePrices[i]就会被填充未初始化的垃圾值(也就是你看到的-858993460)。
2. 修复步骤
方案一:清理输入流的换行符
在读取价格后,手动跳过换行符,确保下一次getline能读到正确的内容:
#include <limits> // 需要包含这个头文件来用numeric_limits void loadArrays(string consoleNames[], int consolePrices[], int& size) { ifstream dataFile("prices.txt"); if (!dataFile) { // 先检查文件是否成功打开 cerr << "无法打开文件!" << endl; size = 0; return; } int i = 0; size = 0; // 初始化size为0,避免传入的初始值干扰 do { // 读取主机名称 if (!getline(dataFile, consoleNames[i])) { break; // 如果读取失败(比如到文件末尾),直接退出循环 } // 读取价格 if (!(dataFile >> consolePrices[i])) { break; } i++; size++; // 跳过价格后面的换行符,避免影响下一次getline dataFile.ignore(numeric_limits<streamsize>::max(), '\n'); if (size == 6) break; } while (true); // 用true循环,靠读取失败或size达标来退出 }
方案二:用整行读取再拆分(更可靠)
因为你的主机名称包含空格(比如Nintendo Entertainment System),如果文件里是主机名和价格在同一行,用getline读取整行后拆分更稳妥,避免因格式问题出错:
#include <sstream> // 需要包含这个头文件来用istringstream void loadArrays(string consoleNames[], int consolePrices[], int& size) { ifstream dataFile("prices.txt"); if (!dataFile) { cerr << "无法打开文件!" << endl; size = 0; return; } int i = 0; size = 0; string line; while (getline(dataFile, line) && size < 6) { // 读取每行,直到文件末尾或size达标 istringstream lineStream(line); // 读取主机名:把行里除了最后一个数字的部分都读出来 string namePart; consoleNames[i] = ""; while (lineStream >> namePart) { // 尝试把namePart转成整数,如果成功就是价格,否则是主机名的一部分 int price; if (istringstream(namePart) >> price) { consolePrices[i] = price; break; } else { if (!consoleNames[i].empty()) consoleNames[i] += " "; consoleNames[i] += namePart; } } i++; size++; } }
3. 代码里的其他小问题
- 你注释里的
if (consolePrices = 0)是赋值操作,不是比较,正确的应该是if (consolePrices[i] == 0),不过更合理的是检查输入流的状态(比如!dataFile)来判断读取是否失败。 size是引用参数,最好在函数里初始化为0,避免调用时传入的初始值导致累加错误。- 要先检查文件是否成功打开,避免文件不存在时直接读取导致崩溃。
内容的提问来源于stack exchange,提问作者GCodes
相关产品推荐
相关产品推荐

