将文件读入struct

时间:2013-12-21 16:19:06

标签: c file-io struct

您好我最近使用c创建了一个程序,但在处理文本文件时遇到了一些问题。这是我的代码(有点长):

 struct std_choice
    {
        char id[6], choice1[3], choice2[3], choice3[3];
    };

    struct std_choice std1[1500]

    int load_std()
    {
        FILE *fp;
        int i=0,j=0,f=1, field=0, format=1, k, l, eof=0;
        char c;

    //initialization
    printf("  initializing array");
    for (k=0; k<1500; k++)
    {   for (l=0; l<6; l++)
        { std1[k].id[l]=0;
         };

         for (l=0; l<3; l++)
        { std1[k].choice1[l]=0;
         }; 

         for (l=0; l<3; l++)
        { std1[k].choice2[l]=0;
        }; 

         for (l=0; l<3; l++)
        { std1[k].choice3[l]=0;
        };

    };
    printf("finished\n");
    printf("  loading the file...");
    fp = fopen("std.txt", "rb");

    if (fp == NULL)
    {   printf("\n\nThe file does not exsist.; 
        return 0;
    }
    else
    {   printf("finished\n  loading student data");
        while (!eof && f && format)
        {    f=0; format=0;
             c= fgetc(fp);

                     if ((c !=58) && (c!=13) && (c!=-1))
             { 
             f = check_valid(&c, 1, 48, 57); // check if the character falls in the range 48-57

                       switch (field)
                       {    
                          case 0:      std1[j].id[i]=c;
                                           format = 1;
                                            break;
                              case 1:      std1[j].choice1[i]=c;
                                           format = 1;
                                            break;
                              case 2:      std1[j].choice2[i]=c;
                                           format = 1;
                                            break;
                              case 3:      std1[j].choice3[i]=c;
                                           format = 1;
                                            break;
                              default:     //error
                                            format=0;
                                            break;
                             };
                           i++;
                           }
                else
                        {   if (c==58)
                            {  
                               f=1;
                               switch (field)
                                { //check the no. of character read     
                                  case 0:  if (i==6) format=1;break;
                                  case 1:  if (i==3) format=1; break;
                                  case 2:  if (i==3) format=1; break;
                         default: format = 0; break;
                                 };
                               if (format==1)
                               field++;
                               i=0;
                              }
                              else   
                 {  //c==13  
                                if (c==13)
                                {  f=1;           
                                  c=fgetc(fp);

                                  if (i==3) //check if the no. of character read = 3
                                    {  format = 1;
                                      j++;
                                      field=0;
                                      i=0;
                                      if ((j%20) == 0) 
                                         printf(".");
                                    }
                                   else
                                      f=0;
                                   }
                                else 
                                {       //EOF
                                        eof=1;
                                        format=1;
                                        totalstd=j;
                                        f=1; 

                               };   
                             };
                        };  


           };

    };

    if (format ==0 || f==0)
    {
        return 0;
    };


    printf("finished\n");
    return 0; 
    };

文本文件是这样的:

012345:000:000:000
123445:123:456:000

(在EOF之前输入)

但我得到的结果真的很奇怪。例如,

std[0].id = 012345000000000123445123456000
std[0].choice1 = 000000000123445123456000
std[0].choice2 = 000123445123456000

我测试了开关部分,似乎当我在案例1中将c的值添加到choice1时,c也被添加到id中......有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:0)

你没有在字符串中考虑NULL字符,结构应该是这样的:

 struct std_choice
    {
        char id[7], choice1[4], choice2[4], choice3[4];
    };

为什么这样做?

Struct成员存储在内存中,以便您声明它们(有时使用额外的填充)。 假设您将012345:abc:def:ghi存储到结构中,Memory将如下所示:

                   V choice2
_______________________________
|0|1|2|3|4|5|a|b|c|d|e|f|g|h|i| ...
-------------------------------
 ^ id        ^           ^
             choice1     choice3

当您阅读id并打印它时,printf函数将从id指向的内容开始读取并打印内存中的字符,直到达到NULL个字符,因此它将打印012345abcdefhgi...,它也可以从下一个结构中读取(它发生在您的示例中),类似地,当您想要打印choice1时,它将从a开始并继续直到达到NULL {1}}(生成abcdefghi...)等等......