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

C++读取文本文件生成密码时ispunct()抛出异常问题求解

问题排查与修复

崩溃根因

你遇到的ispunct位置抛异常是非法内存访问导致的,代码里存在两处明确的下标越界问题:

  • 检查首字母外大写的循环for (int i = b.length(); i; --i),std::string的有效下标范围是0 ~ 长度-1,直接访问b[b.length()]属于越界读,触发未定义行为,直接导致字符判断函数异常。
  • 检查标点、数字的循环for (int i = b.length() - 1; i; --i)终止条件为i非零,i=0时直接停止循环,漏掉了首字符的标点、数字校验。

其他逻辑错误

  • acceptWord的第一个参数string a是值传递,函数内的a = b不会修改外层变量,属于无效代码,冗余参数可以直接删掉。
  • main函数中tokens是初始化的空vector,直接用tokens[i] = token赋值属于越界写,会触发崩溃,需要用push_back方法添加符合条件的单词。
  • rand()仅在程序启动时调用一次,所有密码组合都会使用同一个单词,不符合随机选4个单词的要求。
  • 输出20组密码的逻辑写在读取文件的while循环内,会每读取一个单词就输出20次,逻辑错位。
  • 缺少<cctype>头文件,ispunct/isdigit/isupper等字符处理函数属于该头文件,部分编译器未引入时会有未定义行为。
  • 未初始化随机种子,每次程序运行生成的随机序列完全一致。

修复后代码

#include <iostream>
#include <fstream>
#include <vector>
#include <cctype>
#include <cstdlib>
#include <ctime>
using namespace std;

bool acceptWord(const string& b) {
    // 单词长度至少4位
    if (b.length() <= 3) {
        return false;
    }
    // 检查所有字符无标点、无数字
    for (int i = 0; i < b.length(); ++i) {
        if (ispunct(b[i]) || isdigit(b[i])) {
            return false;
        }
    }
    // 首字母大写的情况下,剩余字母不能大写
    if (isupper(b[0])) {
        for (int i = 1; i < b.length(); ++i) {
            if (isupper(b[i])) {
                return false;
            }
        }
    }
    return true;
}

int main()
{
    srand(time(nullptr)); // 初始化随机种子
    fstream file;
    string word, filename;
    vector<string> tokens;

    filename = "input.txt";
    file.open(filename.c_str());

    if (!file.is_open()) {
        cout << "File not found" << endl;
        exit(1);
    }

    // 读取所有符合条件的单词
    while (file >> word)
    {
        if (acceptWord(word)) {
            tokens.push_back(word);
        }
    }
    file.close();

    // 单词库不足的情况处理
    if (tokens.size() < 4) {
        cout << "符合条件的单词数量不足,无法生成密码" << endl;
        return 1;
    }

    // 输出20组密码,每组4个随机单词
    for (int i = 0; i < 20; ++i) {
        string w1 = tokens[rand() % tokens.size()];
        string w2 = tokens[rand() % tokens.size()];
        string w3 = tokens[rand() % tokens.size()];
        string w4 = tokens[rand() % tokens.size()];
        cout << w1 << " " << w2 << " " << w3 << " " << w4 << endl;
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:06:01