无法将文本文件两行数字分别读入两个vector的问题求助
问题描述
我是编程新手,正在完成编程书籍中练习for循环的习题。习题要求编写程序判断一个vector<int>是否是另一个的前缀:若两个vector长度不等,则比较较短vector的所有元素;例如给定分别包含0、1、1、2和0、1、1、2、3、5、8的vector,程序应返回true。
我尝试将文本文件中的两行数字分别读入两个vector,但无法实现。之前手动给vector赋值时能验证底部的for循环逻辑正确,现在已注释手动赋值部分,寻求文件读取问题的解决方法。
文本文件内容:
0 1 1 2 0 1 1 2 3 5 8
编写的代码如下:
// 练习5.17:给定两个int类型的vector,编写程序判断其中一个是否是另一个的前缀。 // 若两个vector长度不等,则比较较短vector的元素个数。 // 例如,给定分别包含0、1、1、2和0、1、1、2、3、5、8的vector,程序应返回true。 #include <iostream> #include <vector> #include <string> using std::cin; using std::cout; using std::endl; using std::vector; using std::string; int main() { // 创建两个vector变量 vector<int> v1 /*{0, 1, 1, 2} */; vector<int> v2 /*{0, 1, 1, 2, 3, 5, 8} */; // 从控制台读取两行数字到两个不同的vector int n{}; // 读取到新行时切换的标志 bool flag = false; // 输入文件仅包含两行整数 while (cin >> n);{ if (n == '\n') // 遇到新行时翻转标志 flag = true; if (!flag) // 读取第一行数字到第一个vector,直到遇到新行 v1.push_back(n); else // 读取下一行数字到第二个vector v2.push_back(n); } // 比较vector的值,设置布尔标志 bool match = false; if(v1.size() < v2.size()){ // 若v1是较短vector,则比较其元素 for (decltype(v1.size()) index = 0; index != v1.size(); ++index){ if (v1[index] == v2[index]) match = true; else match = false; } } else { for (decltype(v2.size()) index = 0; index != v2.size(); ++index) { // 若v2是较短vector,则比较其元素 if (v1[index] == v2[index]) match = true; else match = false; } } // 将布尔标志转换为"true"或"false" string value; if (match) value = "true"; else value = "false"; // 输出结果 cout << "两个vector是否匹配或vector1是vector2的前缀:'\n'" << value << endl; return 0; }
问题解决
一、文件读取的核心错误修复
你的输入读取逻辑存在两个致命问题:
while (cin >> n);后的分号:这个分号会让循环直接终止,后续代码块仅执行一次,完全无法批量读取数字。- 用
n == '\n'判断换行无效:cin >> n会自动跳过所有空白字符(包括换行、空格),n永远不会等于换行符的ASCII值,因此切换标志的逻辑完全失效。
正确的读取方式是先读取整行,再用字符串流解析每行内的数字。需要新增<sstream>头文件,修改读取代码:
#include <sstream> // 必须包含的头文件 // ... 其他代码 ... string line; // 读取第一行并解析到v1 if (getline(cin, line)) { std::istringstream iss(line); int num; while (iss >> num) { v1.push_back(num); } } // 读取第二行并解析到v2 if (getline(cin, line)) { std::istringstream iss(line); int num; while (iss >> num) { v2.push_back(num); } }
二、前缀判断逻辑的隐性错误
你认为手动赋值时逻辑正确,但实际上存在漏洞:当前代码会覆盖之前的匹配结果,只要最后一个元素相等,match就会被设为true,哪怕前面有不匹配的元素。比如v1为{0,1,2}、v2为{0,3,2}时,代码会错误返回true。
正确逻辑应该是:初始设匹配为true,一旦发现不匹配就立即设为false并跳出循环:
bool match = true; size_t min_size = std::min(v1.size(), v2.size()); for (size_t index = 0; index < min_size; ++index) { if (v1[index] != v2[index]) { match = false; break; // 发现不匹配,直接终止循环 } }
三、完整修正后的代码
// 练习5.17:给定两个int类型的vector,编写程序判断其中一个是否是另一个的前缀。 // 若两个vector长度不等,则比较较短vector的元素个数。 // 例如,给定分别包含0、1、1、2和0、1、1、2、3、5、8的vector,程序应返回true。 #include <iostream> #include <vector> #include <string> #include <sstream> #include <algorithm> // 用于std::min using std::cin; using std::cout; using std::endl; using std::vector; using std::string; using std::istringstream; int main() { vector<int> v1; vector<int> v2; // 读取两行数字到对应vector string line; if (getline(cin, line)) { istringstream iss(line); int num; while (iss >> num) { v1.push_back(num); } } if (getline(cin, line)) { istringstream iss(line); int num; while (iss >> num) { v2.push_back(num); } } // 判断前缀关系 bool match = true; size_t min_size = std::min(v1.size(), v2.size()); for (size_t index = 0; index < min_size; ++index) { if (v1[index] != v2[index]) { match = false; break; } } // 输出结果 cout << "两个vector是否存在前缀关系:" << (match ? "true" : "false") << endl; return 0; }
内容的提问来源于stack exchange,提问作者Pogomogo
相关产品推荐
相关产品推荐

