c编程文本文件结构和FGET中出错

c编程文本文件结构和FGET中出错,c,C,我的程序没有响应,我需要如下输入。 这是我的文本文件: MU-547东航每天10.55 1.20,途经香海+1天 MU-541东航13.50每天1.20,途经香海+1天 CI-835华航每天9点40分16点,途经台北 CI-065华航16.25 1.10每天经台北 SQ-970新加坡航空公司每天20.50 8.40,途经新加坡 SQ-972新加坡航空公司每天20.50 11.05,途经新加坡 SQ-974新加坡航空公司每天20.50 14.35,途经新加坡 SQ-976新加坡航空公司每天20.5

我的程序没有响应,我需要如下输入。
这是我的文本文件:

MU-547东航每天10.55 1.20,途经香海+1天
MU-541东航13.50每天1.20,途经香海+1天
CI-835华航每天9点40分16点,途经台北
CI-065华航16.25 1.10每天经台北
SQ-970新加坡航空公司每天20.50 8.40,途经新加坡
SQ-972新加坡航空公司每天20.50 11.05,途经新加坡
SQ-974新加坡航空公司每天20.50 14.35,途经新加坡
SQ-976新加坡航空公司每天20.50 17.55,途经新加坡
SQ-978新加坡航空公司每天20.50 20.05,途经新加坡
CX-751国泰航空公司9.15每天16.20,通过香港
CX-701国泰航空公司10.45每天17.55,通过香港

#包括
类型定义结构
{
charid[7];
char airlineName[31];
飘来飘去;
字符注释[100];
}航空公司;
void openFile(const char*data2)
{
航空飞机[12]={0};
int i=0;
FILE*FILE=fopen(数据2,“r”);
如果(文件)
{
字符行[83];
while(fgets(行、行大小、文件)和&i<6)
{
FPUT(线路、标准输出);
如果(sscanf)(行,
%6s%30c%f%f%99c“,
平面[i].id,
飞机[i]。航空公司名称,
飞机[我]到达,
飞机,飞机离开,
平面[i]。注)==5)
{
printf(“%s”,平面[i].id);
printf(“%c”,平面[i].airlineName);
printf(“%f”,平面[i]。到达);
printf(“%f”,平面[i]。出发);
printf(“%c”,平面[i]。注释);
i++;
}         
}
fclose(文件);
}
其他的
佩罗尔(数据2);
}
内部主(空)
{
openFile(“data2.txt”);
返回0;
}

正如评论中指出的,声明:
字符行[83]不够大,无法包含输入文件中显示的某些行,从而导致错误。类似地,
struct
中的某些字段的硬编码长度可能不够大,无法包含将来可能提供给您的输入文件。(例如,中的某些航空公司名称长度超过31个字符,并且不适合
char airlineName[31]
)使用
浮动类型,如
到达
离开
等字段可能是安全的。但是
notes
airlines
甚至
id
字段至少有问题。您可能还不知道输入文件中的行数

您可以通过多种方式确定输入文件行长度或行数。我马上想到两个选择:

1)估算线的长度、线的数量和希望 它们对于每个输入文件都是稳定的。(正如你所看到的,这已经发生了 后果)
2)根据需要确定行数和最大行长 一个预处理步骤,然后使用该信息创建 适当大小的输入行字符缓冲区,并使用指向 struct,创建足够的空间,以便在每行数据中包含数据, 不管输入文件包含多少行

例如,创建一个函数以确定文件中的行数和文件中最长行的长度,然后使用该信息创建足够的内存,以便逐行读取文件,而不会出现缓冲区溢出的风险:

int longestline(const char *filename, int *lc)
{
    FILE *fp;
    int cnt=0, cntKeep=0;
    char c;
    (*lc) = 0;
    fp = fopen(filename, "r");
    if(!fp) return 0;
    while ( (c = fgetc ( fp) ) != EOF )
    {
        if(c != '\n') 
        {
            cnt++;
        }
        else 
        {
            cnt = 0;
            (*lc)++; //update line counter
        }
        cntKeep = cntKeep < cnt ? cnt : cntKeep;//update longest line counter
    }
    if(cnt > 0) (*lc)++;//last line may not have '\n'
    fclose(fp);
    return cntKeep;
}

同样的预处理方法也可以扩展到创建适当大小的结构成员变量。通过在每行上使用and函数,并在阅读文件时跟踪每个字段的最长长度,使用类似的方法逐个成员确定最长字段长度。

正如注释中指出的,语句:
字符行[83]不够大,无法包含输入文件中显示的某些行,从而导致错误。类似地,
struct
中的某些字段的硬编码长度可能不够大,无法包含将来可能提供给您的输入文件。(例如,中的某些航空公司名称长度超过31个字符,并且不适合
char airlineName[31]
)使用
浮动类型,如
到达
离开
等字段可能是安全的。但是
notes
airlines
甚至
id
字段至少有问题。您可能还不知道输入文件中的行数

您可以通过多种方式确定输入文件行长度或行数。我马上想到两个选择:

1)估算线的长度、线的数量和希望 它们对于每个输入文件都是稳定的。(正如你所看到的,这已经发生了 后果)
2)根据需要确定行数和最大行长 一个预处理步骤,然后使用该信息创建 适当大小的输入行字符缓冲区,并使用指向 struct,创建足够的空间,以便在每行数据中包含数据, 不管输入文件包含多少行

例如,创建一个函数以确定文件中的行数和文件中最长行的长度,然后使用该信息创建足够的内存,以便逐行读取文件,而不会出现缓冲区溢出的风险:

int longestline(const char *filename, int *lc)
{
    FILE *fp;
    int cnt=0, cntKeep=0;
    char c;
    (*lc) = 0;
    fp = fopen(filename, "r");
    if(!fp) return 0;
    while ( (c = fgetc ( fp) ) != EOF )
    {
        if(c != '\n') 
        {
            cnt++;
        }
        else 
        {
            cnt = 0;
            (*lc)++; //update line counter
        }
        cntKeep = cntKeep < cnt ? cnt : cntKeep;//update longest line counter
    }
    if(cnt > 0) (*lc)++;//last line may not have '\n'
    fclose(fp);
    return cntKeep;
}

同样的预处理方法也可以扩展到创建适当大小的结构成员变量。使用类似的方法确定最长字段长度,每个成员使用扩展到每行上的and函数,并在读取文件时跟踪每个字段的最长长度。

当扫描带有%f的浮点值时,需要变量的地址,并且缺少这些值。
使用%c进行扫描不会以“\0”终止变量,因此printf可能会出现问题。
格式为“%6s%30[^0-9]%f%f%
int line_cnt = 0;
int longestLine = longestline("c:\\inputfile.txt", &line_cnt)//determine longest line of file.
//char line[83];
char *line = calloc(longestLine + 1, 1);//create buffer to accommodate longest of lines found in file
//AIRLINE plane[12] = {0};
AIRLINE *plane = calloc(line_cnt, sizeof(AIRLINE));
#include <stdio.h>
typedef struct
{
    char id[7];
    char airlineName[31];
    float arrive,depart;
    char notes[100];
} AIRLINE;

void openFile(const char *data2)
{
    AIRLINE plane[12] = {{{0}}};
    int i = 0;
    FILE *file = fopen(data2,"r");
    if ( file )
    {
        char line[83];
        while( i < 6 && fgets(line,sizeof line, file))
        {
            fputs(line, stdout);
            if( sscanf(line,"%6s %30[^0-9]%f%f %99[^\n]",
                plane[i].id,
                plane[i].airlineName,
                &plane[i].arrive,       // needed &
                &plane[i].depart,       // needed &
                plane[i].notes) == 5 )
            {
                printf(" %s ",plane[i].id);
                printf(" %s ",plane[i].airlineName);  // use %s for string
                printf(" %f ",plane[i].arrive);
                printf(" %f ",plane[i].depart);
                printf(" %s ",plane[i].notes);
                i++;
            }
        }
        fclose(file);
    }
    else
    {
        perror(data2);
    }
}

int main(void)
{
    openFile("data2.txt");
    return 0;
}