如何将文件读入并行数组及解决EOF判断异常(二维字符串+一维整数)
问题分析与解决方案
核心问题拆解
1. while (!inFile.eof()) 的致命陷阱
C++里eof()只有在尝试读取超出文件末尾后才会返回true。你读完最后一行数据时,eof()仍然是false,会再进入一次循环——此时读取失败,但数组里还存着之前的数据,所以会重复输出。
2. 分隔符与读取逻辑完全错配
你写入的内容用逗号分隔(比如"hello, hola, 0"),但cin >> string默认按**空白字符(空格、换行)**分割,导致hello,被当成一个完整字符串,hola,是另一个,直接让你判断words[r][c] == words[r][SPN_WORDS - 1]的逻辑彻底失效,甚至出现数组越界(比如调试代码里的words[r][SPN_WORDS],下标超出数组范围,触发未定义行为)。
3. endl vs \n 的误解
endl是\n加缓冲区刷新,两者写入文件的换行效果完全一致。你用\n读不出数据的问题,根源是读取逻辑错误,和换行符本身无关。
修正后的代码实现
方案1:改用空格分隔(最简单直接)
#include <iostream> #include <fstream> #include <string> const int ENG_WORDS = 3, SPN_WORDS = 2, SIZE = 3; int main() { std::string words[ENG_WORDS][SPN_WORDS]; int searches[SIZE]; std::ofstream outFile; std::ifstream inFile; // 文件写入:用\n替代endl,空格分隔数据 outFile.open("test.txt"); outFile << "hello hola 0\n" << "bye adios 0\n" << "thanks gracias 0\n"; outFile.close(); // 文件读取:用读取操作作为循环条件,避免eof陷阱 inFile.open("test.txt"); int r = 0; // 每一行读取一组数据,直到文件结束或数组填满 while (r < ENG_WORDS && inFile >> words[r][0] >> words[r][1] >> searches[r]) { std::cout << words[r][0] << " " << words[r][1] << " " << searches[r] << "\n"; r++; } inFile.close(); return 0; }
方案2:保留逗号分隔的文件格式
如果必须用逗号分隔,需要手动处理分隔符:
#include <iostream> #include <fstream> #include <string> #include <sstream> const int ENG_WORDS = 3, SPN_WORDS = 2, SIZE = 3; int main() { std::string words[ENG_WORDS][SPN_WORDS]; int searches[SIZE]; std::ofstream outFile; std::ifstream inFile; // 文件写入:保留逗号分隔,用\n替代endl outFile.open("test.txt"); outFile << "hello, hola, 0\n" << "bye, adios, 0\n" << "thanks, gracias, 0\n"; outFile.close(); // 文件读取:按行读取后拆分内容 inFile.open("test.txt"); std::string line; int r = 0; while (std::getline(inFile, line) && r < ENG_WORDS) { std::stringstream ss(line); std::string temp; // 读取英文单词,跳过逗号 std::getline(ss, temp, ','); words[r][0] = temp.substr(0, temp.find_last_not_of(" ")); // 去掉可能的空格 // 读取西班牙文单词,跳过逗号 std::getline(ss, temp, ','); words[r][1] = temp.substr(0, temp.find_last_not_of(" ")); // 读取搜索次数 ss >> searches[r]; std::cout << words[r][0] << " " << words[r][1] << " " << searches[r] << "\n"; r++; } inFile.close(); return 0; }
关键知识点总结
- 绝对不要用
while (!inFile.eof()):必须用读取操作的返回值作为循环条件(比如while (inFile >> var)或while (getline(inFile, line))),确保只有读取成功时才处理数据。 - 输入分隔符要对应:
cin >>默认按空白分割,用其他分隔符(如逗号)时,必须用getline(stream, var, delimiter)手动处理。 endl能不用就不用:频繁刷新缓冲区会降低IO效率,文件写入用\n完全足够。- 杜绝数组越界:数组下标从0开始,最大下标是
长度-1,越界会导致无限循环、垃圾值等未定义行为。
内容的提问来源于stack exchange,提问作者Loading Screen
相关产品推荐
相关产品推荐

