【问题标题】:How can I read a txt file and place the information into struct in C?如何读取 txt 文件并将信息放入 C 中的 struct 中?
【发布时间】:2021-01-20 11:23:13
【问题描述】:

我正在尝试读取 txt 文件并将信息放入 C 类项目的结构中。我的代码似乎没有读取文件并将信息放入结构中。我阅读了许多博客文章,但找不到或纠正我的错误。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 

struct flightData {
    char airline[9];
    int flightCode;
    char departureAirport[3];
    char destinationAirport[3];
    int passengerCapacity;
    int depTimeHour;
    int depTimeMin;
    int arvTimeHour;
    int arvTimeMin;
};

int main(){ 
   FILE *flightFile;
   flightFile = fopen("flights.txt","r");
    int flightCount=0;
   struct flightData input[10];
   if (flightFile == NULL) 
    { 
        fprintf(stderr, "\nError opening file\n"); 
        exit (1); 
    } 
   while (fscanf(flightFile,"%s %d %s %s %d %d:%d %d:%d", input[flightCount].airline,&input[flightCount].flightCode,input[flightCount].departureAirport,input[flightCount].destinationAirport
            ,&input[flightCount].passengerCapacity,&input[flightCount].depTimeHour,&input[flightCount].depTimeMin,&input[flightCount].arvTimeHour,&input[flightCount].arvTimeMin)!= EOF){
      
        flightCount++;
      printf ("%s\n",input[flightCount].airline);

   }
fclose(flightFile);
    return 0;
}

这里是 .txt 文件

THY 12345 IST DUD 10 20:05 16:10
LUFTHANSA 23356 IST MUC 10 11:55 12:40
PEGASUS 34567 SAW MUC 10 12:20 17:00
PEGASUS 45678 SAW XSP 10 01:55 17:20
EMIRATES 67890 ADB HKG 10 19:45 15:50
THY 78901 SAW IST 10 07:20 08:25

从这段代码中我得到了这个结果:

X����

P+�

【问题讨论】:

  • [3] 太短而无法存储,例如 "LHR"。它需要[4] 以在读取时使用%3s 限制输入。另请比较 fscanf== 9 而不是 != EOF
  • \nError opening file\n 是无用错误消息的典型示例。告诉用户导致问题的路径,并报告问题所在。 perror("flights.txt")
  • ...而char airline[9]; 太短,无法存储"LUFTHANSA"。它至少需要为[10],并且%s 没有长度限制是等待发生的损坏。

标签: c struct fread


【解决方案1】:

您必须切勿scanf 中使用"%s"。不比gets好。要在 scanf 中安全地使用%s,您必须在转换说明符中使用比缓冲区大小小一的最大字段宽度。 scanf 将读取不超过指定的字符数,并将写入读取的字符加上空终止符。您的代码中还有一些其他(大部分是微不足道的)问题。尝试类似:

int                                                                                
main(int argc, char **argv)                                                        
{                                                                                  
        const char *path = argc > 1 ? argv[1] : "flights.txt";                     
        FILE *flightFile = fopen(path,"r");                                        
        int flightCount=0;                                                         
        struct flightData input[10], *t = input;                                   
        if( flightFile == NULL ) {                                                 
                perror(path);                                                      
                return EXIT_FAILURE;                                               
        }                                                                          
        char fmt[128];                                                             
        snprintf(fmt, sizeof fmt, "%%%zus %%d %%%zus %%%zus %%d %%d:%%d %%d:%%d",  
                sizeof t->airline - 1, sizeof t->departureAirport - 1,             
                sizeof t->destinationAirport - 1);                                 
                                                                                   
        while( fscanf(flightFile, fmt, t->airline, &t->flightCode,                 
                t->departureAirport, t->destinationAirport,                        
                &t->passengerCapacity, &t->depTimeHour, &t->depTimeMin,            
                &t->arvTimeHour, &t->arvTimeMin) == 9 )                            
        {                                                                          
                t += 1;                                                            
        }                                                                          
        fclose(flightFile);                                                        
        flightCount = t - input;                                                   
                                                                                   
        for( int i = 0; i < flightCount; i++ ){                                    
                printf("%s\n", input[i].airline);                                  
        }                                                                          
        return 0;                                                                  
}

请注意,您可能需要添加一些额外的诊断。鉴于您当前的结构定义(其中字符串太小),此示例将进入 while 循环的主体零次并将flightCount 设置为零,因为scanf 将无法读取第一行输入.处理留给读者作为练习。

【讨论】:

    【解决方案2】:

    除了问题cmets中提到的错误之外,最严重的错误是行

            flightCount++;
          printf ("%s\n",input[flightCount].airline);
    

    其中索引flightCount 在访问input 数组之前递增,因此检索到未初始化的值。把这两行交换一下,按照上面cmet推荐的做,效果会好很多。

    【讨论】:

    • 非常感谢!这解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2020-10-07
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2022-11-19
    相关资源
    最近更新 更多