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

C++文件处理代码运行时错误的检测与修复咨询

你的C++文件处理代码运行时错误的原因及修复方案

看起来你的代码编译通过但运行崩溃,核心原因是二进制读写包含std::string的结构体导致的未定义行为,再加上一些逻辑细节错误。下面我会逐一拆解问题并给出修复方案:

核心问题:std::string的二进制序列化陷阱

你的car结构体里包含std::string color和std::string size,但std::string内部存储的是指向堆内存的指针、字符串长度等元数据,并非实际的字符串内容。当你用file.write((char*)&ccc, sizeof(ccc))直接写入整个结构体时,写入的是这些指针值,而不是字符串本身。读取时,这些指针指向的内存早已失效(或者不属于当前进程),直接访问就会触发程序崩溃。

解决这个问题最简单的方式是把std::string替换为固定长度的char数组(适合简单的文件存储场景):

struct car
{
    char name[20];
    int  model;
    char color[20];  // 替换std::string为char数组
    int car_id;
    char size[20];   // 替换std::string为char数组
    float weight;
    int price;
};

其他运行时错误点修复

1. modify函数的无限循环与指针偏移错误

  • 原代码的while循环里没有读取下一个记录,会一直卡在当前记录导致无限循环;
  • seekg(0, ios::cur)是多余的,修改时需要定位到当前记录的起始位置,而非当前读取位置。

修复后的modify函数:

void modify()
{
    car ccc;
    fstream file;
    char n_c[20];
    file.open("carinformation.dat", ios::binary | ios::in | ios::out);
    if(!file)
    {
        cout<<"File not found";
        exit(EXIT_FAILURE);
    }
    cout<<"\nEnter name of car that should be searched:";
    cin>>n_c;
    streampos pos;
    bool found = false;
    while(file.read((char*)&ccc, sizeof(ccc)))
    {
        pos = file.tellg(); // 保存下一个记录的位置
        if(strcmp(n_c, ccc.name)==0)
        {
            // 回到当前记录的起始位置
            file.seekp(pos - sizeof(ccc));
            cout<<"Enter new record :\n";
            getdata(ccc);
            file.write((char*)&ccc, sizeof(ccc));
            cout<<"Record modified successfully!\n";
            found = true;
            break; // 如需修改所有匹配记录,可移除break
        }
    }
    if(!found)
    {
        cout<<"No record found with name: "<<n_c<<"\n";
    }
    file.close();
}

2. deleterecord函数的文件名拼写错误与逻辑问题

  • 原代码中remove("carinfomation.dat")拼写错误,正确文件名是carinformation.dat(少了一个'r');
  • 关闭file后又尝试调用file.read,会触发未定义行为;
  • 重复使用count变量但未重置,导致统计结果错误。

修复后的deleterecord函数:

void deleterecord()
{
    int count = 0;
    car ccc;
    int c_id;
    cout<<"Please enter car id :";
    cin>>c_id;
    ifstream file("carinformation.dat", ios::binary | ios::in);
    if(!file)
    {
        cout<<"File not found";
        exit(EXIT_FAILURE);
    }
    ofstream file2("New_carinformation.dat", ios::binary | ios::out);
    // 复制非目标ID的记录
    while(file.read((char*)&ccc, sizeof(ccc)))
    {
        if(ccc.car_id != c_id)
        {
            file2.write((char*)&ccc, sizeof(ccc));
            count++;
        }
    }
    cout<<"Number of remaining records are :"<<count<<"\n";
    file.close();
    file2.close();

    // 替换原文件
    remove("carinformation.dat");
    rename("New_carinformation.dat", "carinformation.dat");

    // 验证删除后的文件内容
    cout<<"\nRecords after deletion:\n";
    count = 0;
    ifstream new_file("carinformation.dat", ios::binary | ios::in);
    while(new_file.read((char*)&ccc, sizeof(ccc)))
    {
        count++;
        showdata(ccc);
    }
    cout<<"Total records after deletion: "<<count<<"\n";
    new_file.close();
}

3. 移除非标准头文件conio.h

#include<conio.h>是非标准头文件,很多现代编译器(如GCC、Clang)不支持,且你的代码并未使用该头文件的任何函数,直接删除即可。

4. 优化EOF判断逻辑

原代码while(!file.eof())的写法可能导致最后一条记录被重复读取,优化为直接在while条件中判断读取是否成功,示例如下(readdata函数):

void readdata()
{
    int count=0;
    ifstream file;
    car ccc;
    file.open("carinformation.dat", ios::binary | ios::in);
    if(!file)
    {
        cout<<"File not found";
        exit(EXIT_FAILURE);
    }
    while(file.read((char*)&ccc, sizeof(ccc)))
    {
        showdata(ccc);
        count++;
    }
    cout<<"\nNumber of records are :"<<count;
    file.close();
}

完整修复后的代码

#include<iostream>
#include<cstring>  // 替换<string.h>为标准C++头文件
#include<fstream>
#include<cstdlib>  // 用于EXIT_FAILURE常量
using namespace std;

struct car
{
    char name[20];
    int  model;
    char color[20];
    int car_id;
    char size[20];
    float weight;
    int price;
};

void getdata(car&);
void showdata(car&);
void searchdata();
void deleterecord();
void modify();
void readdata();
void writedata();

int main()
{
    char ch;
    cout<<"\nEnter w to write record ";
    cout<<"\nEnter r to read record";
    cout<<"\nEnter m to modify record";
    cout<<"\nEnter s to search record";
    cout<<"\nEnter d to delete record";
    cout<<"\n\nEnter your choice :";
    cin>>ch;

    switch(ch)
    {
        case 'w':
            writedata();
            break;
        case 'r':
            readdata();
            break;
        case 's':
            searchdata();
            break;
        case 'd':
            deleterecord();
            break;
        case 'm':
            modify();
            break;
        default:
            cout<<"\nWrong choice";
    }
    return 0;
}

void getdata(car &ccc)
{
    cout<<"Please enter name of car :";
    cin>>ccc.name;
    cout<<"Please enter model number of car:";
    cin>>ccc.model;
    cout<<"Enter color of car:";
    cin>>ccc.color;
    cout<<"Enter id number of car:";
    cin>>ccc.car_id;
    cout<<"Enter size of car :";
    cin>>ccc.size;
    cout<<"Enter weight of a car :";
    cin>>ccc.weight;
    cout<<"Enter price of a car :";
    cin>>ccc.price;
}

void showdata(car &ccc)
{
    cout<<"\nName of car is :"<<ccc.name;
    cout<<"\nModel number of car is :"<<ccc.model;
    cout<<"\nColor of car is :"<<ccc.color;
    cout<<"\nID number of car is :"<<ccc.car_id;
    cout<<"\nSize of car is :"<<ccc.size;
    cout<<"\nWeight of car is :"<<ccc.weight;
    cout<<"\nPrice of car is :"<<ccc.price<<"\n";
}

void writedata()
{
    ofstream file;
    char ch='y';
    car ccc;
    file.open("carinformation.dat",ios::binary | ios::out | ios::app);
    while(ch=='y'|| ch=='Y')
    {
        getdata(ccc);
        file.write((char*)&ccc,sizeof(ccc));
        cout<<"\nDo you want to continue?";
        cin>>ch;
    }
    file.close();
}

void readdata()
{
    int count=0;
    ifstream file;
    car ccc;
    file.open("carinformation.dat", ios::binary | ios::in);
    if(!file)
    {
        cout<<"File not found";
        exit(EXIT_FAILURE);
    }
    while(file.read((char*)&ccc, sizeof(ccc)))
    {
        showdata(ccc);
        count++;
    }
    cout<<"\nNumber of records are :"<<count;
    file.close();
}

void searchdata()
{
    car ccc;
    ifstream file;
    char n_c[20];
    cout<<"Enter name of car :";
    cin>>n_c;
    file.open("carinformation.dat", ios::binary | ios::in);
    if(!file)
    {
        cout<<"File not found";
        exit(EXIT_FAILURE);
    }
    bool found = false;
    while(file.read((char*)&ccc, sizeof(ccc)))
    {
        if(strcmp(n_c,ccc.name)==0)
        {
            showdata(ccc);
            found = true;
        }
    }
    if(!found)
    {
        cout<<"No record found with name: "<<n_c<<"\n";
    }
    file.close();
}

void modify()
{
    car ccc;
    fstream file;
    char n_c[20];
    file.open("carinformation.dat", ios::binary | ios::in | ios::out);
    if(!file)
    {
        cout<<"File not found";
        exit(EXIT_FAILURE);
    }
    cout<<"\nEnter name of car that should be searched:";
    cin>>n_c;
    streampos pos;
    bool found = false;
    while(file.read((char*)&ccc, sizeof(ccc)))
    {
        pos = file.tellg();
        if(strcmp(n_c, ccc.name)==0)
        {
            file.seekp(pos - sizeof(ccc));
            cout<<"Enter new record :\n";
            getdata(ccc);
            file.write((char*)&ccc, sizeof(ccc));
            cout<<"Record modified successfully!\n";
            found = true;
            break;
        }
    }
    if(!found)
    {
        cout<<"No record found with name: "<<n_c<<"\n";
    }
    file.close();
}

void deleterecord()
{
    int count = 0;
    car ccc;
    int c_id;
    cout<<"Please enter car id :";
    cin>>c_id;
    ifstream file("carinformation.dat", ios::binary | ios::in);
    if(!file)
    {
        cout<<"File not found";
        exit(EXIT_FAILURE);
    }
    ofstream file2("New_carinformation.dat", ios::binary | ios::out);
    while(file.read((char*)&ccc, sizeof(ccc)))
    {
        if(ccc.car_id != c_id)
        {
            file2.write((char*)&ccc, sizeof(ccc));
            count++;
        }
    }
    cout<<"Number of remaining records are :"<<count<<"\n";
    file.close();
    file2.close();

    remove("carinformation.dat");
    rename("New_carinformation.dat", "carinformation.dat");

    cout<<"\nRecords after deletion:\n";
    count = 0;
    ifstream new_file("carinformation.dat", ios::binary | ios::in);
    while(new_file.read((char*)&ccc, sizeof(ccc)))
    {
        count++;
        showdata(ccc);
    }
    cout<<"Total records after deletion: "<<count<<"\n";
    new_file.close();
}

额外细节优化

  • 替换string.h为标准C头文件cstring,符合C规范;
  • 使用EXIT_FAILURE代替0作为exit()的参数,语义更清晰;
  • 增加了记录是否找到的提示,提升用户体验;
  • 修正了writedata中的拼写错误(countine→continue)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:33:59