如何让std::cin仅读取输入的指定部分,提取每行目标数字
问题根因
你的代码存在两个核心逻辑错误:
- 调用
cin >> N读取完第一行的行数后,输入缓冲区还残留第一行末尾的换行符,第一次执行cin.ignore时会优先处理这个换行符,完全不符合你预期的「从第二行开头跳过5个字符」的逻辑。 cin.ignore(5, ' ')的规则是最多跳过5个字符,或者碰到空格就立刻停止,不会跳过5个字符后再找空格。同时你没有做行边界处理,每次循环读取完一个数值后会接着当前缓冲区位置继续处理,不会自动跳到下一行开头,3次循环其实只处理了第一行的前3个分隔数值,根本没有用到后面两行的输入,所以你会误以为输入完第一行程序就停止了。
你的示例输入的字符流完整顺序是:3\n1111 22 3 4444 5555\n1111 2 3 4444 5555\n1111 22 33 4444 5555\n
执行流程完全对应你得到的错误输出:
- 读走
3后缓冲区残留\n+后续所有内容 - 第一次循环:
ignore跳过\n+4个1(刚好凑够5个字符),读取到22写入data[0] - 第二次循环:
ignore碰到读取22后残留的空格直接停止,读取到3写入data[1] - 第三次循环:
ignore碰到读取3后残留的空格直接停止,读取到4444写入data[2] - 循环结束直接输出结果,程序退出
修复方案
推荐用逐行读取的方式实现,不需要手动计算跳过字符数,鲁棒性更高,哪怕后续第一位数字的长度变化也不会出错:
#include <iostream> #include <string> #include <sstream> using namespace std; int main() { int N = 0; cin >> N; cin.ignore(); // 清空读取N后残留的换行符 int data[100]; for(int i=0; i<N; i++) { string line; getline(cin, line); // 读取完整的一行内容 istringstream line_stream(line); // 将当前行转为独立输入流处理 int discard; line_stream >> discard; // 跳过第一个数字 line_stream >> data[i]; // 直接读取第二个数字,就是你需要的目标值 } for(int i=0; i<N; i++) { cout << data[i] << endl; } return 0; }
如果你坚持要用ignore实现,也可以调整为按行边界处理的版本:
int main() { int N = 0; cin >> N; cin.ignore(1024, '\n'); // 直接跳到第一行末尾,清空所有残留 int data[100]; for(int i=0; i<N; i++) { cin.ignore(1024, ' '); // 跳过当前行第一个空格前的所有内容(第一个数字) cin >> data[i]; cin.ignore(1024, '\n'); // 跳过当前行剩余内容,直接跳到下一行开头 } for(int i=0; i<N; i++) { cout << data[i] << endl; } return 0; }
内容的提问来源于stack exchange,提问作者Endre555
相关产品推荐
相关产品推荐

