2015-11-21 127 views
1

我有2个结构:军医病人。我必须从2个不同的.txt文档中读取数据,然后在控制台中显示它。
我正在使用CodeBlocks。当我试图调试这个时,发现this发生在citireM被执行后。我问我的老师,并做了一些谷歌搜索,但无济于事。这个函数让.exe崩溃,我做错了什么?

#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. Jouleau; medic stomatolog; 
    32 Michael Bush; medic chirurg; 
    88 Ceva Nume Lung Aici; medic neidentificat; 

patients.txt

 

    2 
    321 Insert Name Here; Timisoara, judetul Timis; 2 5 1991 
    123 Insert Some Other Name Here; Nu se stie unde traieste; 1 6 1654 

+0

检查'l'中的内容,并在将'p'传递给'strcpy()'之前确保'p'不是'NULL'。 – MikeCAT

+0

这次崩溃应该意味着你写过一个本地数组的末尾。唯一有意义的本地数组就是'l',我看不到任何可以写入结尾的方式。对于'm'结尾的写作我没有看到任何防御。这不应该完全符合症状,但无论如何你应该有一些防御措施,它可能是你追逐的错误。 – JSF

+0

一个更基本的问题是C字符串是C语言中初学者错误的最大来源,并且通常是真实字符串的近似值。您标记了您的问题C++,而不是C(并使用C++流)。那么为什么你使用C字符串和C数组,其中std :: string和std :: vector更有意义? – JSF

回答

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型功能给你,让你没有在项目中包含额外的东西。

+0

*您现在已经阅读了这一行,现在您正在尝试阅读日期变量中的内容。* 那么这基本上意味着我必须彻底改变我的想法。 是的,这是一个我一直在努力工作近一个星期的家庭作业。我只是不知道如何从txt输入整个医疗/患者的姓名(或任何其他长度未知,空格分隔的字符/字符串)。 – David

+0

@David你需要使用getline吗? –

+0

不,我只需要使用string.h。使用getline和通过strtok分离数据是我的想法。 – David