fread()是c中的一个结构

fread()是c中的一个结构,c,struct,io,fread,C,Struct,Io,Fread,对于我的任务,我需要使用fread/fwrite。我写 #include <stdio.h> #include <string.h> struct rec{ int account; char name[100]; double balance; }; int main() { struct rec rec1; int c; FILE *fptr; fptr = fopen("clients.txt", "r"

对于我的任务,我需要使用fread/fwrite。我写

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

struct rec{
    int account;
    char name[100];
    double balance;
};

int main()
{
    struct rec rec1;
    int c;

    FILE *fptr;
    fptr = fopen("clients.txt", "r");

    if (fptr == NULL)
        printf("File could not be opened, exiting program.\n");
    else
    {
        printf("%-10s%-13s%s\n", "Account", "Name", "Balance");
        while (!feof(fptr))
        {
            //fscanf(fptr, "%d%s%lf", &rec.account, rec.name, &rec.balance);
            fread(&rec1, sizeof(rec1),1, fptr);
            printf("%d %s %f\n", rec1.account, rec1.name, rec1.balance);
        }
        fclose(fptr);
    }
    return 0;
}
#包括
#包括
结构记录{
国际账户;
字符名[100];
双平衡;
};
int main()
{
结构rec rec1;
INTC;
文件*fptr;
fptr=fopen(“clients.txt”,“r”);
如果(fptr==NULL)
printf(“无法打开文件,正在退出程序。\n”);
其他的
{
printf(“%-10s%-13s%s\n”、“账户”、“名称”、“余额”);
而(!feof(fptr))
{
//fscanf(fptr、%d%s%lf、&rec.account、rec.name和rec.balance);
fread(&rec1,sizeof(rec1),1,fptr);
printf(“%d%s%f\n”,rec1.account,rec1.name,rec1.balance);
}
fclose(fptr);
}
返回0;
}
clients.txt文件

100 Jones 564.90 200 Rita 54.23 300 Richard -45.00 100琼斯564.90 200丽塔54.23 300里查德-45.00里查德 输出

Account Name Balance 540028977 Jones 564.90 200 Rita 54.23 300 Richard -45.00╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠ü☻§9x°é -92559631349317831000000000000000000000000000000000000000000000.000000 Press any key to continue . . . 账户名称余额 540028977琼斯564.90 200丽塔54.23 300里查德-45.00里查德╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠ü☻§9x°-92559631349317831000000000000000000000000000000000000000000000.000000 按任意键继续。 我可以用fscanf(我已经注释掉了),但是我需要使用fread/fwrite

  • 为什么一开始Jone的账户就有一个庞大的数字
  • 为什么后面有垃圾?费奥夫不应该阻止这一切吗
  • 使用这种方法有什么缺点吗?还是fscanf方法
  • 我怎样才能修好这些?
    事先非常感谢

    正如评论所说,
    fread
    读取文件中的字节而不进行任何解释。文件
    clients.txt
    由50个字符组成,第一行16个字符,第二行14个字符,第三行18个字符,加上两个换行字符。(您的clients.txt在第三行之后不包含换行符,您很快就会看到。)换行符在UNIX或Mac OS X机器上是一个单字节
    \n
    ,但在Windows机器上(可能)是两个字节
    \r\n
    ,因此可以是50或51个字符。以下是十六进制ASCII字节序列:

    3130 3020 4a6f 6e65 7320 3536 342e 3930     100 Jones 564.90
    0a32 3030 2052 6974 6120 3534 2e32 330a     \n200 Rita 54.23\n
    3330 3020 5269 6368 6172 6420 2d34 352e     300 Richard -45.
    3030                                        00
    
    您的
    fread
    语句将这些字节复制到
    rec1
    数据结构中,而不进行任何解释。该结构以
    int账户开始
    ,表示将前四个字节解释为
    int
    。正如其中一条评论所指出的,您正在一台小型endian机器(很可能是Intel机器)上运行程序,因此最低有效字节是第一个,最高有效字节是第四个。因此,您的
    fread
    将四个ASCII字符的序列
    “100”
    解释为四字节整数
    0x20303031
    ,以十进制表示等于
    540028977
    。结构的下一个成员是
    charname[100]
    ,这意味着
    rec1
    中接下来的100字节数据将是
    名称。但是
    fread
    被告知读取
    sizeof(rec1)=112个字节(4字节帐户,100字节名称,8字节余额)。由于您的文件只有50(或52)个字符,
    fread
    只能填充
    rec1
    的那么多字节。如果您没有放弃,
    fread
    的返回值会告诉您,读取停止的字节数少于您请求的字节数。由于您点击了EOF,在第一次通过后,
    feof
    调用中断循环,一口吞下了整个文件

    您的所有输出都是通过对
    fprintf
    的第一次也是唯一一次调用生成的。编号540028977和以下空格由
    %d”
    rec1.account
    参数生成。下一位只是部分确定的,幸运的是:
    “%s”
    说明符和相应的
    rec1.name
    参数将以ASCII格式打印下一个字符,直到找到
    \0
    字节。因此,输出将以文件中剩余的
    50-4
    (或
    52-4
    )字符(包括两个换行符)开始,并可能永远持续,因为文件(或任何文本文件)中没有
    \0
    字节,这意味着在打印文件的最后一个字符后,您看到的是程序启动时自动变量
    rec1
    中出现的垃圾。(这种无意的输出类似于OpenSSL中著名的heartbleed bug。)幸运的是,垃圾仅在几十个字符之后就包含了一个
    \0
    字节。请注意,
    printf
    无法知道
    rec1.name
    被声明为仅100字节数组——它只得到指向
    name
    开头的指针——您有责任保证
    rec1.name
    包含终止的
    \0
    字节,而您从未这样做过

    我们可以说得更多一点。数字
    -9.2559631349317831e61
    (在
    %f
    格式中非常难看)是
    rec1.balance
    的值。IEEE 754机器(如您的Intel和所有现代计算机)上的
    double
    值的8字节是十六进制
    0xcccc
    。六十四个奇特的
    符号出现在与
    rec1.name
    相对应的
    %s”
    输出中,而100个字符中只剩下100-46=54个字符,因此您的
    %s”
    输出已从
    rec1.name
    结束,并将
    rec1.balance
    包含在交易中,我们了解到,您的终端程序将非ASCII字符
    0xcc
    解释为
    。有许多方法可以解释大于127(0x7f)的字节;在拉丁语-1中,它应该是
    Ì例如。图形字符
    是古代MS-D中0xcc(204)字节的表示形式
    struct rec recs[] = {{100, "Jones", 564.90},
                         {200, "Rita", 54.23},
                         {300, "Richard", -45.00}};