TJL2011-C++-C- 2024-02-07 15:49 采纳率: 0%
浏览 4

程序运行时抛出异常,无法运行

#include<bits/stdc++.h>
#define ull unsigned long long
#define MAX_STR_LEN 1024
using namespace std;

//template<typename Type>
//string to_string(const Type& t){
//    ostringstream oss;
//    oss<<t;
//    return oss.str();
//}
/*
//en/decode
char szInput[MAX_STR_LEN] = { 0 };
char szOutput[2 * MAX_STR_LEN] = { 0 };
char szInputConvert[MAX_STR_LEN] = { 0 };

typedef unsigned char BYTE;
namespace CodeConvert {
    static BYTE GetTransFlag() { //生成随机8位二进制字节
        return (rand() % 256 & 0xFF);//生成一个随机数,取最后一个字节
    }

    int ConvertByteToCode(BYTE *pbDest, const BYTE *pbSrc) { //加密
        int nLen = strlen((char*)pbSrc);//获取数据长度(若信息中有0x00间隔,修改函数将长度作为入参)
        if (nLen <= 0) {
            return 0;
        }
        BYTE TransFlag = GetTransFlag();//用于异或运算的一字节
        BYTE byTempSrc[MAX_STR_LEN] = { 0 };
        memcpy(byTempSrc, pbSrc, nLen);
        byTempSrc[nLen] = TransFlag;
        for (int i = 0; i < nLen; ++i) {
            byTempSrc[i] ^= TransFlag >> (i % 8);
        }
        char sztmp[4];
        for (int i = 0; i <= nLen; ++i) {
            sprintf(sztmp, "%02X", byTempSrc[i]);
            strcat((char*)pbDest, sztmp);
        }
        return (2 * nLen + 2);
    }

    int ConvertCodeToByte(BYTE *pbDest, const BYTE *pbSrc) { //解密
        int nLenSrc = strlen((char*)pbSrc);
        int nLenDes = nLenSrc / 2;
        if (nLenDes <= 0) {
            return 0;
        }
        //将字符串转换为字节
        BYTE h1, h2;
        BYTE s1, s2;
        for (int i = 0; i < nLenDes; i++) {
            h1 = pbSrc[2 * i];
            h2 = pbSrc[2 * i + 1];
            s1 = toupper(h1) - 0x30;
            if (s1 > 9)
                s1 -= 7;
            s2 = toupper(h2) - 0x30;
            if (s2 > 9)
                s2 -= 7;
            pbDest[i] = s1 * 16 + s2;
        }
        //解密为原字符
        for (int i = 0; i < nLenDes - 1; ++i) {
            pbDest[i] ^= pbDest[nLenDes - 1] >> (i % 8);
        }
        pbDest[nLenDes - 1] = 0x00;
        return nLenDes - 1;
    }
    int doEncode(bool type) {
        memset(szInput, 0, sizeof(szInput));
        memset(szOutput, 0, sizeof(szOutput));
        memset(szInputConvert, 0, sizeof(szInputConvert));
        if (type)return CodeConvert::ConvertByteToCode((BYTE*)szOutput, (BYTE*)szInput);
        else return CodeConvert::ConvertCodeToByte((BYTE*)szInputConvert, (BYTE*)szOutput);
    }
}*/

struct PlayerAtti {
    int PlayerLevel, GameLevel;
    int MaxBlood, NowBlood, PlayerDefense;
    int AttackSpeed, AttackHurt;
    int Weapon;
    int PlayerType;
    int PlayerBuffType;
    int PlayerBuff;
    int Money;
    string tmp;
} Player;

namespace V0_1 {
    void PrintMainMenu();
    void GetPlayerSelection();
    void SaveFile();
    void ReadFile();
    void StartGame();
    void NewGame();
    void GameSetting();
    void CheatMode();
}

int WeaponHurtType1[12] = {5, 10, 20, 50, 20, 40, 90, 100, 105, 150, 10000, INT_MAX};
int WeaponBuffType1[12] = {0, 0, 0, 0, 0, 30, 70, 80, 90, 95, 500, INT_MAX};
int WeaponHurtType2[12] = {10, 20, 35, 70, 90, 100, 150, 300, 500, 700, 10000, INT_MAX};
int WeaponBuffType2[12] = {10, 30, 45, 60, 75, 80, 100, 80, 90, 95, 500, INT_MAX};

int main() {
    srand(time(NULL));
    Player.AttackHurt=rand();
    Player.AttackSpeed=rand();
    Player.GameLevel=rand();
    Player.MaxBlood=rand();
    Player.Money=rand();
    Player.NowBlood=rand();
    Player.PlayerBuff=rand();
    Player.PlayerBuffType=rand();
    Player.PlayerDefense=rand();
    Player.PlayerLevel=rand();
    Player.PlayerType=rand();
    Player.Weapon=rand();
    V0_1::SaveFile();
//    V0_1::PrintMainMenu();
//    V0_1::GetPlayerSelection();
//    V0_1::StartGame();
    return 0;
}

void V0_1::ReadFile() {
    string num;
    string s = ".\\saves\\", s2 = ".TJLgameFILE";
    cout << "请输入存档文件名称:";
    cin >> num;
    ifstream in(s.append(num.append(s2)));
    in >> Player.tmp >> Player.AttackHurt;
    in >> Player.tmp >> Player.AttackSpeed;
    in >> Player.tmp >> Player.GameLevel;
    in >> Player.tmp >> Player.MaxBlood;
    in >> Player.tmp >> Player.NowBlood;
    in >> Player.tmp >> Player.PlayerLevel;
    in >> Player.tmp >> Player.PlayerType;
    in >> Player.tmp >> Player.Weapon;
    in >> Player.tmp >> Player.PlayerBuffType;
    in >> Player.tmp >> Player.PlayerBuff;
    in >> Player.tmp >> Player.Money;
}

void V0_1::SaveFile() {
//    string num;
//    string s = ".\\saves\\", s2 = ".TJLGAMESAVEFILE";
//    cout << "请输入保存存档文件名称:";
//    cin >> num;
    //ofstream out(s.append(num.append(s2)));
    ofstream ikun(/*".\\saves\\jntm.TJLGAMEFILE"*/"jntm.txt");
//    out << "AttackHurt:"     << Player.AttackHurt << '\n';
//    out << "AttackSpeed:"    << Player.AttackSpeed << '\n';
//    out << "GameLevel:"       << Player.GameLevel << '\n';
//    out << "MaxBlood:"       << Player.MaxBlood << '\n';
//    out << "NowBlood:"       << Player.NowBlood << '\n';
//    out << "PlayerLevel"     << Player.PlayerLevel << '\n';
//    out << "PlayType:"       << Player.PlayerType << '\n';
//    out << "PlayerWeapon"    << Player.Weapon << '\n';
//    out << "PlayerBuffType:" << Player.PlayerBuffType << '\n';
//    out << "PlayerBuff:"      << Player.PlayerBuff << '\n';
//    out << "Money:"         << Player.Money << '\n';
    ikun << "Please Don't Try To Edit This File,Because That Will Make Your Savefile Damage.\n";
    ikun << "请不要试着编辑这个游戏存档文件,这会使您的存档损坏。\n";
    string x[13] = {0, "AttackHurt:", "AttackSpeed:", "GameLevel:", "MaxBlood:", "NowBlood:", "PlayerLevel", "PlayerType:", "PlayerDefense" ,"PlayerWeapon", "PlayerBuffType:", "PlayerBuff:", "Money:" };
    string str="";
    str.append(x[1].append(to_string(Player.AttackHurt)));
    str.append(x[2].append(to_string(Player.AttackSpeed)));
    str.append(x[3].append(to_string(Player.GameLevel)));
    str.append(x[4].append(to_string(Player.MaxBlood)));
    str.append(x[5].append(to_string(Player.NowBlood)));
    str.append(x[6].append(to_string(Player.PlayerLevel)));
    str.append(x[7].append(to_string(Player.PlayerType)));
    str.append(x[8].append(to_string(Player.PlayerDefense)));
    str.append(x[9].append(to_string(Player.Weapon)));
    str.append(x[10].append(to_string(Player.PlayerBuffType)));
    str.append(x[11].append(to_string(Player.PlayerBuff)));
    str.append(x[12].append(to_string(Player.Money)));
    ikun << "TOKEN:"<<str;
}

void V0_1::PrintMainMenu() {
    printf("|-------------------------------------------|\n");
    printf("|         ----欢迎来到TJL的游戏----         |\n");
    printf("|                1.创建新存档               |\n");
    printf("|                 2.读取存档                |\n");
    printf("|                 3.游戏设置                |\n");
    printf("|-------------------------------------------|\n");
    printf("|-------------------------------------------|\n");
    cout << "请选择:[ ]\b\b";
    char choice;
    cin >> choice;
    switch (choice) {
        case '1':
//            V0_1::NewGame();
            break;
        case '2':
            V0_1::ReadFile();
            break;
        case '3':
//            V0_1::GameSetting();
            break;
        case 't':
//            V0_1::CheatMode();
            break;
        default:
            cout << "输入错误!(╯▔皿▔)╯⊥__⊥";
            return;
    }
}

程序编译后运行时抛出如下异常:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid

C++编译命令:

g++.exe "C:\Users\TJL\Desktop\NewProject\Main.cpp" -o "C:\Users\TJL\Desktop\NewProject\Main.exe" -Wall -Wextra -g3 -finput-charset=gbk -fexec-charset=gbk -I"E:\DEVC++\MinGW64\include\c++\10.3.0" -I"E:\DEVC++\MinGW64\include\c++\10.3.0\x86_64-w64-mingw32" -I"E:\DEVC++\MinGW64\include\c++\10.3.0\backward" -I"E:\DEVC++\MinGW64\lib\gcc\x86_64-w64-mingw32\10.3.0\include" -I"E:\DEVC++\MinGW64\include" -I"E:\DEVC++\MinGW64\lib\gcc\x86_64-w64-mingw32\10.3.0\include-fixed" -I"E:\DEVC++\MinGW64\x86_64-w64-mingw32\include" -L"E:\DEVC++\MinGW64\lib\gcc\x86_64-w64-mingw32\10.3.0\" -L"E:\DEVC++\MinGW64\lib\gcc\" -L"E:\DEVC++\MinGW64\x86_64-w64-mingw32\lib\" -L"E:\DEVC++\MinGW64\lib\" -L"E:\DEVC++\MinGW64\lib" -L"E:\DEVC++\MinGW64\x86_64-w64-mingw32\lib" -g3 -lgdi32 -static
  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-07 15:51
    关注

    引自免费微信小程序:皆我百晓生

    根据您提供的错误信息 "terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid",问题在于C++标准库中的std::string试图使用一个空指针进行构造或操作。这个错误通常发生在你尝试用NULL或未初始化的指针来初始化或赋值给std::string对象时。

    在您的代码中,最可能触发此错误的位置是V0_1::ReadFile()函数内的文件读取部分:

    ifstream in(s.append(num.append(s2)));
    //...
    in >> Player.tmp >> Player.AttackHurt;
    

    这里,Player.tmp是一个std::string对象,在没有预先初始化的情况下直接用于从输入流中读取字符串。当读取到非字符串数据(比如这里的整数Player.AttackHurt)之前,并没有先读取任何字符串内容,因此Player.tmp实际上是未初始化的状态。

    为了解决这个问题,您可以更改代码以确保在读取整数值之前先正确读取和处理字符串数据。例如,可以添加一行来实际读取一个临时字符串变量,然后跳过它:

    void V0_1::ReadFile() {
        // ...
        string tempStr;
        ifstream in(s.append(num.append(s2)));
        // 读取并忽略首个字符串
        getline(in, tempStr);
        // 现在安全地读取 AttackHurt 等整数值
        in >> Player.AttackHurt;
        // 继续读取其他成员变量
        // ...
    }
    

    不过,请注意这仅基于当前提供的上下文。如果Player.tmp实际上应该保存某个有意义的字符串,则需要检查原始设计意图,确保正确初始化该字符串并在读取前适当地处理输入流中的数据格式。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月7日

悬赏问题

  • ¥15 依据报错在原代吗格式的基础上解决问题
  • ¥15 在虚拟机中安装flash code
  • ¥15 单片机stm32f10x编写光敏电阻调节3.3伏大功率灯亮度(光强越大灯越暗,白天正常光强灯不亮,使用ADC,PWM等模块)望各位找一下错误或者提供一个可实现功能的代码
  • ¥20 verilog状态机方法流水灯
  • ¥15 pandas代码实现不了意图
  • ¥15 GD32H7 从存储器到外设SPI传输数据无法重复启用DMA
  • ¥25 LT码在高斯信道下的误码率仿真
  • ¥45 渲染完成之后将物体的材质贴图改变,自动化进行这个操作
  • ¥15 yolov5目标检测并显示目标出现的时间或视频帧
  • ¥15 电视版的优酷可以设置电影连续播放吗?