You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++控制台行反转程序触发SIGINT中断的原因及修正方案

问题分析与修复:VSCode+g++环境下vector逆序遍历触发SIGINT中断

我来帮你拆解下这个问题的根源,以及对应的修复方案——你的代码里有几个关键的细节错误,最终导致了程序停滞和SIGINT中断:

一、导致问题的核心原因

1. string::substr 参数用错了

你写的 strLines.substr(oldIndex, newIndex+1) 是错误的!C++里substr的第二个参数是要截取的长度,不是结束位置的索引。这会导致每次截取的字符串长度远超预期,甚至越界读取内存,最后存入vector的内容全是混乱的,后续遍历自然会触发未定义行为(比如SIGINT)。

2. 画蛇添足的'\0'

string类型本身会自动管理末尾的终止符,你手动给每个字符串加'\0'完全没必要,反而会让输出出现奇怪的空字符或乱码,干扰程序正常运行。

3. 逆序遍历的循环逻辑有漏洞

原循环:

for (vector<string>::iterator it = strVector.end()-1 ; it != strVector.begin(); it--)
  • 如果输入的内容是空的(比如直接按EOF),strVector.end()-1就是非法迭代器(空容器的end和begin是同一个位置,减1直接越界),这会直接触发崩溃或SIGINT。
  • 循环条件it != strVector.begin()会漏掉第一个元素(也就是原输入的第一行),而且遍历到begin就停止,无法完成完整的逆序输出。

4. 读取EOF时写入了无效字符

getc(stdin)返回的EOF是int类型的-1,你直接把它转成char加到字符串里,会存入一个无效的0xFF字符,导致后续的字符串查找和截取逻辑出错。

二、一步步修复代码

1. 修复字符读取逻辑

先判断是否为EOF,再添加有效字符到字符串:

int c;
while ((c = getc(stdin)) != EOF) {
    strLines += static_cast<char>(c);
}

2. 修正substr的使用方式

正确计算截取长度,并且去掉多余的'\0':

string strToPush = strLines.substr(oldIndex, newIndex - oldIndex);
strVector.push_back(strToPush);

3. 用更安全的方式逆序遍历

推荐用反向迭代器,这完全符合你最初的思路,而且不需要手动处理迭代器边界,安全又简洁:

for (vector<string>::reverse_iterator it = strVector.rbegin(); it != strVector.rend(); ++it) {
    cout << *it << endl;
    // 如果想保留原输入的换行符,改成cout << *it;就行
}

要是你坚持用普通迭代器,记得先判断vector是否为空,再调整循环条件确保遍历所有元素:

if (!strVector.empty()) {
    for (auto it = strVector.end() - 1;; --it) {
        cout << *it;
        if (it == strVector.begin()) break;
    }
}

4. 处理最后一行无换行的情况

原代码会漏掉没有以换行结尾的最后一行,新增这个逻辑补上:

if (newIndex == string::npos) {
    // 如果还有未处理的内容,添加最后一行
    if (oldIndex < strLines.size()) {
        strVector.push_back(strLines.substr(oldIndex));
    }
    break;
}

三、完整的修复后代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main() {
    string strLines;
    int c;
    // 修复字符读取,避免写入EOF无效字符
    while ((c = getc(stdin)) != EOF) {
        strLines += static_cast<char>(c);
    }

    size_t oldIndex = 0;
    size_t newIndex;
    vector<string> strVector;

    // 正确截取每行内容,处理最后一行无换行的情况
    while (true) {
        newIndex = strLines.find('\n', oldIndex);
        if (newIndex == string::npos) {
            if (oldIndex < strLines.size()) {
                strVector.push_back(strLines.substr(oldIndex));
            }
            break;
        }
        string strToPush = strLines.substr(oldIndex, newIndex - oldIndex);
        strVector.push_back(strToPush);
        oldIndex = newIndex + 1;
    }

    // 反向迭代器安全逆序输出
    for (auto it = strVector.rbegin(); it != strVector.rend(); ++it) {
        cout << *it << endl;
    }

    return 0;
}

额外提示

  • 在VSCode终端输入EOF的方式:Windows按Ctrl+Z,Linux/macOS按Ctrl+D。
  • C++11及以上版本可以用auto简化迭代器声明,代码会更清爽。

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:07:52