用c语言读取文件时出错

时间:2014-01-06 09:41:13

标签: c

我编写了以下用于将数据写入文件的代码

#include<stdio.h>
struct bank{
    int accn;
    char last[10];
    char first[15];
    double bal;
};
int main()
{
    FILE *ptr;
    int i;
    struct bank cl={0," "," ",0.00};
    printf("%d %d %d\n",sizeof(struct bank),sizeof(int),sizeof(double));
    if ((ptr=fopen("banking_r.dat","wb"))==NULL)
        printf("file can't be opened");
    else
        {
            printf("enter account number,last name,first name and balance\n");
            fprintf(ptr,"%s%10s%10s %s\n","account no","last name","first name","balance");
            for (i=1;i<=2;i++)
            {
                fscanf(stdin,"%d%10s%10s%lf",&cl.accn,cl.last,cl.first,&cl.bal);
                fseek(ptr,(cl.accn-1)*sizeof(struct bank),SEEK_SET);
                printf("%d\n",sizeof(struct bank));
                fwrite(&cl,sizeof(struct bank ),1,ptr);
                fprintf(ptr,"\n");}
                fclose(ptr);
            }
            return 0;
        }

之后我输入数据

1 parker peter 23.89
2 parker arnold 23.45

然后,我写了下面的代码来读取文件

#include<stdio.h>
struct bank{
    int accn;
    char last[10];
    char first[15];
    double bal;
};
int main()
{
    FILE *ptr;
    struct bank cl;
    if ((ptr=fopen("banking_r.dat","rb"))==NULL)
        printf("file can not be opened");
    else {
        while(!feof(ptr)) {
            fread(&cl,sizeof(struct bank),1,ptr);
            //if (cl.accn!=0)
            printf("%-4d %-10s %-10s %-4.2f\n",cl.accn,cl.last,cl.first,cl.bal) ;
        }
    }
        return 0;
}

,我得到的输出是

1  parker peter 23.89
2  parker arnold 23.45
10 parker arnold 23.45

为什么最后一行打印在输出中?

3 个答案:

答案 0 :(得分:2)

在while循环的第二次迭代之后,

1  parker peter 23.89
2  parker arnold 23.45

fread()语句已执行两次
即现在文件位置向前移动sizeof(struct bank) 两次

此时您希望while循环终止,但它会再次执行。

第三次读取剩余的一个字节,即\n换行符(0x0a)。因此,打印的第3行只是第2行,第一行设置为10 - 0x0a的十进制表示,由于%-4d中使用了printf()

10 parker arnold 23.45

请参阅this question的答案,了解为什么feof() 在示例中使用 来读入文件的全部内容。

替代方法:

  1. 只要fread()返回非零(读入的字符数),就启动并循环。

  2. fread()返回0时,请使用feof()确定其是否为读取错误文件的结尾。

  3. 示例代码段:

    while( fread(&cl, sizeof(struct bank), 1, ptr) != 1 ) {
        // Another complete line read-in to 1 instance of struct bank, print it.
        printf("%-4d %-10s %-10s %-4.2f\n",cl.accn,cl.last,cl.first,cl.bal);
    }
    
    if(!feof(ptr)) {
        // flow comes here ONLY if while loop was terminated due to an fread() error
    }
    

答案 1 :(得分:0)

using feof to find end of the file is wrong.。还可以使用fgetssscanf来阅读该文件。还有很多其他方法可供选择。

此代码可以使用

#include<stdio.h>
#include <stdlib.h>
struct bank{
    int accn;
    char last[10];
    char first[15];
    double bal;
};
int main()
{
FILE *ptr;
char buf[128];
struct bank *cl = malloc(sizeof(struct bank));
if ((ptr=fopen("banking_r.dat","rb"))==NULL)
    printf("file can not be opened");

else {

    while(fgets(buf, sizeof(buf), ptr)) 
    {
        sscanf(buf, "%d %s %s %lf", &cl->accn,cl->last,cl->first, &cl->bal);
        printf("%-4d %-10s %-10s %-4.2f\n",cl->accn,cl->last,cl->first,cl->bal) ;
    }
}
free(cl);
return 0;
}

答案 2 :(得分:0)

@TheCodeArtist指出正确。只需添加,您可以对代码进行以下更改

#include<stdio.h>
struct bank{
    int accn;
    char last[10];
    char first[15];
    double bal;
};
int main()
{
    FILE *ptr;
    struct bank cl;
    if ((ptr=fopen("banking_r.dat","rb"))==NULL)
        printf("file can not be opened");
    else {
            fread(&cl,sizeof(struct bank),1,ptr); //Add before the while loop once

        while(!feof(ptr)) {
            //if (cl.accn!=0)
            printf("%-4d %-10s %-10s %-4.2f\n",cl.accn,cl.last,cl.first,cl.bal) ;

            fread(&cl,sizeof(struct bank),1,ptr); //And again to read more data. If EOF is encountered, this will cause it to break the loop
        }
    }
        return 0;
}