【问题标题】:This function makes the .exe crash, what am I doing wrong?此功能使 .exe 崩溃,我做错了什么?
【发布时间】:2015-11-21 12:48:46
【问题描述】:

我有 2 个结构:medicpatient。我必须从 2 个不同的 .txt 文档中读取数据,然后在控制台中显示。
我正在使用代码块。当我尝试调试它时,我发现this 发生在 citireM 执行之后。我问了我的老师,并做了一些谷歌搜索,但无济于事。

#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
struct date
{
    int d,m,y;
};
struct medic
{
    int cod;
    char name[50],specs[50];
};
struct patient
{
    int cod;
    date bd;
    char name[50],adress[50];
};
struct consultatie
{
    int codp,codm;
    date dc;
    char diag[100];
};
void citireM(medic M[], int &n)
{
    int i; char * p; char l[50];
    ifstream f("medics.txt");
    f>>n;
    for(i=0;i<n;i++)
    {
        strcpy(l,"");
        f>>M[i].cod;
        f.getline(l,50);
        p=strtok(l,";");
        strcpy(M[i].name,p);
        p=strtok(NULL,";");
        strcpy(M[i].specs,p);
    }
}
void citireP(patient P[], int &n)
{
    char * p; char l[50];
    ifstream ff("patients.txt");
    ff>>n;
    for(int i=0;i<n;i++)
    {
        ff>>P[i].cod;
        strcpy(l,"");
        ff.getline(l,50);
        p=strtok(l,";");
        strcpy(P[i].name,p);
        p=strtok(NULL,";");
        strcpy(P[i].adress,p);
        ff>>P[i].bd.d>>P[i].bd.m>>P[i].bd.y;
    }
}
void printM(medic M[], int n)
{
    for (int i=0;i<n;i++)
        cout<<M[i].cod<<" "<<M[i].name<<" "<<M[i].specs;
}
void printP(patient P[], int n)
{
    int i;
    for (i=0;i<n;i++)
        cout<<P[i].cod<<" "<<P[i].name<<" "<<P[i].adress<<" "<<P[i].bd.d<<"/"<<P[i].bd.m<<"/"<<P[i].bd.y;
}
int main()
{
    medic m[30];
    patient p[300];
    int nm,np;
    citireM(m,nm);
    citireP(p,np);
    printM(m,nm);
    printP(p,np);
    return 0;
}

medics.txt

3 007 J.J.焦耳;口腔医学; 32 迈克尔·布什;医治; 88 Ceva Nume Lung Aici;医务人员身份证明;

患者.txt

2 321 在此处插入姓名;蒂米什瓦拉, judetul Timis; 2 5 1991 123 在这里插入一些其他的名字; Nu se stie unde traieste; 1 6 1654

【问题讨论】:

  • 检查l 中的内容,并确保p 不是NULL,然后再将其传递给strcpy()
  • 这个崩溃应该意味着你写了一个本地数组的末尾。唯一有意义的本地数组是l,我看不出有什么办法可以写到它的末尾。我认为在m 结束后写作没有任何理由。这不应该完全符合症状,但无论如何你应该有一些防御措施,而且它可能是你正在追逐的错误。
  • 一个更基本的问题是 C 字符串是 C 中初学者错误的最大来源,并且通常是真正字符串的烂近似值。您标记了您的问题 C++,而不是 C(并使用 C++ 流)。那么为什么在 std::string 和 std::vector 更有意义的地方使用 C 字符串和 C 数组呢?
  • 你也应该发布你的txt文件。
  • medics.txtpatients.txt @JSF 我使用这些是因为我的学校要求我使用这些。我个人更喜欢 std::string 因为我发现它更容易使用。

标签: c++ c crash codeblocks


【解决方案1】:

我正在努力使您的功能与您的功能相同。不过,有很多更清洁的方法可以做到这一点。这也没有考虑到您输入文件的错误,但我只是想让您走上正确的轨道。

int char_to_int(char* src)
{
    int res = 0;
    for(int i = 0; src[i] != '\0'; ++i) {
        res = res * 10 + src[i] - '0';
    }
    return res;
}

void citireP(patient P[], int &n)
{
    const int BUFFER_SIZE = 256;
    char* p; char l[BUFFER_SIZE];
    char* date;
    ifstream ff("patients.txt",ios_base::skipws);
    ff >> n;
    char input[3][BUFFER_SIZE];
    for(int i = 0; i<n; i++) {
        ff >> P[i].cod;
        strcpy(l, "");
        ff.getline(l,BUFFER_SIZE);
        p = strtok(l, ";");
        strcpy(P[i].name, p);
        p = strtok(NULL, ";");
        strcpy(P[i].adress, p);
        p = strtok(NULL, ";");
        date = strtok(p, " ");
        P[i].bd.d = char_to_int(date);
        date = strtok(NULL, " ");
        P[i].bd.m = char_to_int(date);
        date = strtok(NULL, " ");
        P[i].bd.y = char_to_int(date);
    }
}

编辑...

我刚刚为你写了一个 atoi 类型的函数,所以你没有在你的项目中包含额外的东西。

【讨论】:

  • 您已经阅读了这一行,现在您正在尝试阅读 date 变量的下一个内容。 这基本上意味着我必须彻底改变我的想法。是的,这是一个我已经苦苦挣扎了将近一周的家庭作业。我只是不知道如何从 txt 中输入整个医生/患者的姓名(或任何其他长度未知且以空格分隔的字符/字符串)。
  • @David 你需要使用 getline 吗?
  • 不,我只需要使用 string.h。使用 getline 并通过 strtok 分离数据是我的想法。
  • 你只是想要答案,还是因为这是家庭作业,所以想让我帮你得到答案?
  • 两者都适合我。哪个会浪费你的时间。
猜你喜欢
  • 2015-11-21
  • 2023-01-19
  • 2013-08-06
  • 2013-10-21
  • 2016-12-01
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
  • 2020-10-01
相关资源
最近更新 更多