C 阅读的最佳方式&;是否存储此输入?

C 阅读的最佳方式&;是否存储此输入?,c,C,我有一个名为animals.dat的输入文件,其数据格式如下: 1,Allegra,Pseudois nayaur,S,5 2,unknown,Ailurus fulgens,X,10 3,Athena,Moschus fuscus,X,2 我用来存储和处理数据的代码如下。但是,出于某种原因,它似乎陷入了一个无限循环。关于如何使这一点正确/更好,有什么建议吗 void choice3(FILE *infile) { int id; printf("Enter ID ");

我有一个名为
animals.dat
的输入文件,其数据格式如下:

1,Allegra,Pseudois nayaur,S,5 
2,unknown,Ailurus fulgens,X,10
3,Athena,Moschus fuscus,X,2
我用来存储和处理数据的代码如下。但是,出于某种原因,它似乎陷入了一个无限循环。关于如何使这一点正确/更好,有什么建议吗

void choice3(FILE *infile) {
    int id;
    printf("Enter ID ");
    scanf("%d", &id);
    while(!feof(infile)) { 
        int animalID;
        char animalName[20];
        char animalType[20];
        char animalSize;
        int animalAge;
        fscanf(infile,"%d,",&animalID);
        fscanf(infile,"%[^,] ",animalName);
        fscanf(infile,"%s, %c, %d",animalType,&animalSize,&animalAge);
        if(animalID == id) {
            printf("Animal Found");  
        }
    }
    rewind(infile);
编辑:

这是指向我必须作为输入的确切二进制文件的链接

我对这部分的说明是 “所有动物都按id编号的递增顺序列出,从值1开始。如果id编号中有一个洞, e、 那么结构信息仍然存在于文件中,除了名称组件包含字符串之外 “未知”表示空记录。请确保搜索使用随机文件处理。 如果输入了无效的id(在本例中为1或3以外的任何值),则程序将显示错误消息。 否则,将显示动物记录。无论哪种情况,程序都将返回初始菜单。“

我已经按照给定的顺序对此代码进行了更新

void choice3(FILE *infile) {
    Animal tempAnimal;
    int id;
    printf("Enter ID ");
    scanf(" %d", &id);
    fseek(infile,id * sizeof(struct animal),SEEK_SET);
    fread(&tempAnimal,sizeof(struct animal),1,infile);
    printf("%d -- %s\n",tempAnimal->id,tempAnimal->name);
}
我已经在另一个文件animal.h中定义了该结构,其中包括

struct animal {
    short int id;
    char name[20];
    char species[35];
    char size;
    short int age;
};
typedef struct animal* Animal;

但是,由于某种原因,我现在得到了一个“分割错误:11”。这意味着它在我的fread()线上不起作用。有什么建议吗?

这段代码对我很有用-我已经把它做成了一个接近MCVE的东西(:

并非
fscanf()
格式字符串中的所有空格都是必需的;没有任何空格是有害的。请注意,代码会检查字段的正确数量并退出循环。请注意,打印数据是为了清除读取的内容-这是一种基本的调试技术。循环后的测试是对
feof()的正确使用
;使用
feof()
来控制循环几乎总是错误的

您最好使用行读取功能(例如POSIX)读取一行数据,然后您可以打印、扫描、重新扫描、报告导致故障的行。这通常会导致更好的错误报告,只要您有整行可用,而不是
fscanf()之后剩下的任何片段
已读取部分但不是所有字段

还要注意的是,这不适用于包含逗号的双引号或其他一些标准CSV约定的字段。这些确实需要库代码来处理读取

最后,此编辑只涉及将数据读入局部变量并避免“无限循环”。有关存储的讨论,请参阅


animals.dat
来自谷歌硬盘 2017-12-03 19:00:00-08:00提供的
anivers.dat
文件是一个二进制文件,使用问题中概述的60字节结构(并在下面的打印代码中使用)使用小端整数(英特尔机器)编写。如果不可用,以下是包含相同数据的C数组定义的
xxd-i animals.dat的输出:

unsigned char animals_dat[] = {
  0x01, 0x00, 0x41, 0x62, 0x69, 0x67, 0x61, 0x69, 0x6c, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x61,
  0x70, 0x72, 0x69, 0x63, 0x6f, 0x72, 0x6e, 0x69, 0x73, 0x20, 0x73, 0x75,
  0x6d, 0x61, 0x74, 0x72, 0x61, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x08, 0x00,
  0x02, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4f, 0x72,
  0x79, 0x78, 0x20, 0x6c, 0x65, 0x75, 0x63, 0x6f, 0x72, 0x79, 0x78, 0x00,
  0x6d, 0x61, 0x74, 0x72, 0x61, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0c, 0x00,
  0x03, 0x00, 0x41, 0x64, 0x72, 0x69, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x65,
  0x70, 0x68, 0x61, 0x6c, 0x6f, 0x70, 0x68, 0x75, 0x73, 0x20, 0x64, 0x6f,
  0x72, 0x73, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4c, 0x10, 0x00,
  0x04, 0x00, 0x41, 0x68, 0x6d, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4e, 0x61,
  0x65, 0x6d, 0x6f, 0x72, 0x68, 0x65, 0x64, 0x75, 0x73, 0x20, 0x67, 0x72,
  0x69, 0x73, 0x65, 0x75, 0x73, 0x00, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4c, 0x0a, 0x00,
  0x05, 0x00, 0x41, 0x69, 0x64, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4e, 0x61,
  0x65, 0x6d, 0x6f, 0x72, 0x68, 0x65, 0x64, 0x75, 0x73, 0x20, 0x63, 0x61,
  0x75, 0x64, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x58, 0x09, 0x00,
  0x06, 0x00, 0x41, 0x6c, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x50, 0x73,
  0x65, 0x75, 0x64, 0x6f, 0x69, 0x73, 0x20, 0x6e, 0x61, 0x79, 0x61, 0x75,
  0x72, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x05, 0x00,
  0x07, 0x00, 0x41, 0x6d, 0x65, 0x6c, 0x61, 0x00, 0x61, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x65,
  0x72, 0x64, 0x6f, 0x63, 0x79, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x75,
  0x73, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0b, 0x00,
  0x08, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x61,
  0x70, 0x72, 0x61, 0x20, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x6e, 0x65, 0x72,
  0x69, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x01, 0x00,
  0x09, 0x00, 0x41, 0x6e, 0x6a, 0x6f, 0x6c, 0x69, 0x65, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x41, 0x69,
  0x6c, 0x75, 0x72, 0x75, 0x73, 0x20, 0x66, 0x75, 0x6c, 0x67, 0x65, 0x6e,
  0x73, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4c, 0x0a, 0x00,
  0x0a, 0x00, 0x41, 0x74, 0x68, 0x65, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4d, 0x6f,
  0x73, 0x63, 0x68, 0x75, 0x73, 0x20, 0x66, 0x75, 0x73, 0x63, 0x75, 0x73,
  0x00, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x05, 0x00,
  0x0b, 0x00, 0x41, 0x76, 0x61, 0x00, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x65,
  0x70, 0x68, 0x61, 0x6c, 0x6f, 0x70, 0x68, 0x75, 0x73, 0x20, 0x6a, 0x65,
  0x6e, 0x74, 0x69, 0x6e, 0x6b, 0x69, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0d, 0x00,
  0x0c, 0x00, 0x41, 0x78, 0x65, 0x6c, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x48, 0x69,
  0x70, 0x70, 0x6f, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x75, 0x73, 0x20, 0x61,
  0x6e, 0x74, 0x69, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0b, 0x00,
  0x0d, 0x00, 0x41, 0x79, 0x61, 0x6e, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x47, 0x61,
  0x7a, 0x65, 0x6c, 0x6c, 0x61, 0x20, 0x63, 0x75, 0x76, 0x69, 0x65, 0x72,
  0x69, 0x00, 0x69, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x0c, 0x00,
  0x0e, 0x00, 0x42, 0x72, 0x61, 0x64, 0x6c, 0x65, 0x79, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x42, 0x75,
  0x62, 0x61, 0x6c, 0x75, 0x73, 0x20, 0x6d, 0x69, 0x6e, 0x64, 0x6f, 0x72,
  0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x58, 0x04, 0x00,
  0x0f, 0x00, 0x42, 0x72, 0x65, 0x6e, 0x64, 0x61, 0x6e, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x42, 0x6f,
  0x73, 0x20, 0x67, 0x61, 0x75, 0x72, 0x75, 0x73, 0x00, 0x64, 0x6f, 0x72,
  0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x58, 0x01, 0x00
};
unsigned int animals_dat_len = 900;

读取二进制animals.dat的代码 正如我在下面的评论中所指出的,数据文件泄漏信息是因为在每个名称后面都有来自上一条记录的垃圾数据。这是的空填充行为实际上变得有用的情况之一;它使用空字节清除来自上一条记录的无关数据,但当
anies.dat
已生成

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

struct animal {
    short int id;
    char name[20];
    char species[35];
    char size;
    short int age;
};

static void debris_field(const char *tag, const char *field, size_t length)
{
    size_t nomlen = strlen(field);
    int count = 0;
    for (size_t i = nomlen; i < length; i++)
    {
        if (field[i] != '\0')
        {
            if (count == 0)
                printf("%8s (%2zu = %-20s) has debris:\n        ", tag, nomlen, field);
            count++;
            unsigned char u = field[i];
            if (isprint(u))
                putchar(u);
            else
                printf("\\x%.2X", u);
        }
    }
    if (count != 0)
        putchar('\n');
}

static void report_debris(const struct animal *info)
{
    debris_field("name", info->name, sizeof(info->name));
    debris_field("species", info->species, sizeof(info->species));
}

static void choice2(FILE *infile, int noisy)
{
    struct animal info;
    while (fread(&info, sizeof(info), 1, infile) == 1)
    {
        if (strcmp(info.name, "unknown") == 0)
        {
            printf("Deleted: %2d %20s %30s %c %2d\n", info.id, info.name, info.species, info.size, info.age);
        }
        else
        {
            printf("Current: %2d %20s %30s %c %2d\n", info.id, info.name, info.species, info.size, info.age);
        }
        if (noisy)
            report_debris(&info);
    }
}

int main(int argc, char **argv)
{
    int noisy = 0;
    if (argc > 1 && argv[argc] == 0)    // Use argv
        noisy = 1;
    choice2(stdin, noisy);
    return 0;
}
如果代码没有以某种方式使用
argv
,编译器会抱怨,代码也不会编译

输出-无参数
Current:1 Abigail Capricornis Sumatransis S 8
已删除:2只未知大羚羊M 12
当前:3 Adrian Cephalophus dorsalis L 16
电流:4 Ahmed Naemorhedus griseus L 10
电流:5 Aidan Naemorhedus caudatus X 9
当前:6假性快板nayaur S 5
当前:7 Amela Cerdocyon千米11
删除:8个未知的Capra falconeri M 1
当前:9 Anjolie Ailurus fulgens L 10
电流:10雅典娜麝香S 5
当前:11 Ava Cephalophus jentinki 13岁
当前:12 Axel Hippocamelus抗血清M 11
当前版本:13 Ayanna Gazella cuvieri S 12
现役:14名布拉德利·布巴卢斯·明多伦西斯X 4
当前:15布伦丹·博斯·高鲁x1
输出-带参数
Current:1 Abigail Capricornis Sumatransis S 8
名称(7=Abigail)有碎片:
\x04t\x01t\x01
物种(24=苏门答腊摩羯座)有碎屑:
\?\x1B\O\x1B\
已删除:2只未知大羚羊M 12
名称(7=未知)包含碎片:
\x04t\x01t\x01
物种(13=大羚羊)有碎片:
matraensis\?\x1B\O\x1B\
当前:3 Adrian Cephalophus dorsalis L 16
姓名(6=阿德里安)有碎片:
\x04t\x01t\x01
物种(20=头足类背足类)有碎屑:
sis\?\x1B\O\x1B\
电流:4 Ahmed Naemorhedus griseus L 10
名称(5=艾哈迈德)有碎片:
\x04t\x01t\x01
物种(19=Naemorhedus griseus)有碎片:
sis\?\x1B\O\x1B\
电流:5 Aidan Naemorhedus caudatus X 9
名称(5=艾丹)有碎片:
\x04t\x01t\x01
物种(20=尾状纳莫黑藻)有碎屑:
sis\?\x1B\O\x1B\
当前:6假性快板nayaur S 5
名称(7=Allegra)有碎片:
\x04t\x01t\x01
物种(15=假纳亚尔)有碎片:
状态\?\x1B\O\x1B\
电流:7 A
unsigned char animals_dat[] = {
  0x01, 0x00, 0x41, 0x62, 0x69, 0x67, 0x61, 0x69, 0x6c, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x61,
  0x70, 0x72, 0x69, 0x63, 0x6f, 0x72, 0x6e, 0x69, 0x73, 0x20, 0x73, 0x75,
  0x6d, 0x61, 0x74, 0x72, 0x61, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x08, 0x00,
  0x02, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4f, 0x72,
  0x79, 0x78, 0x20, 0x6c, 0x65, 0x75, 0x63, 0x6f, 0x72, 0x79, 0x78, 0x00,
  0x6d, 0x61, 0x74, 0x72, 0x61, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0c, 0x00,
  0x03, 0x00, 0x41, 0x64, 0x72, 0x69, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x65,
  0x70, 0x68, 0x61, 0x6c, 0x6f, 0x70, 0x68, 0x75, 0x73, 0x20, 0x64, 0x6f,
  0x72, 0x73, 0x61, 0x6c, 0x69, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4c, 0x10, 0x00,
  0x04, 0x00, 0x41, 0x68, 0x6d, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4e, 0x61,
  0x65, 0x6d, 0x6f, 0x72, 0x68, 0x65, 0x64, 0x75, 0x73, 0x20, 0x67, 0x72,
  0x69, 0x73, 0x65, 0x75, 0x73, 0x00, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4c, 0x0a, 0x00,
  0x05, 0x00, 0x41, 0x69, 0x64, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4e, 0x61,
  0x65, 0x6d, 0x6f, 0x72, 0x68, 0x65, 0x64, 0x75, 0x73, 0x20, 0x63, 0x61,
  0x75, 0x64, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x58, 0x09, 0x00,
  0x06, 0x00, 0x41, 0x6c, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x50, 0x73,
  0x65, 0x75, 0x64, 0x6f, 0x69, 0x73, 0x20, 0x6e, 0x61, 0x79, 0x61, 0x75,
  0x72, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x05, 0x00,
  0x07, 0x00, 0x41, 0x6d, 0x65, 0x6c, 0x61, 0x00, 0x61, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x65,
  0x72, 0x64, 0x6f, 0x63, 0x79, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x75,
  0x73, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0b, 0x00,
  0x08, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x61,
  0x70, 0x72, 0x61, 0x20, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x6e, 0x65, 0x72,
  0x69, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x01, 0x00,
  0x09, 0x00, 0x41, 0x6e, 0x6a, 0x6f, 0x6c, 0x69, 0x65, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x41, 0x69,
  0x6c, 0x75, 0x72, 0x75, 0x73, 0x20, 0x66, 0x75, 0x6c, 0x67, 0x65, 0x6e,
  0x73, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4c, 0x0a, 0x00,
  0x0a, 0x00, 0x41, 0x74, 0x68, 0x65, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x4d, 0x6f,
  0x73, 0x63, 0x68, 0x75, 0x73, 0x20, 0x66, 0x75, 0x73, 0x63, 0x75, 0x73,
  0x00, 0x00, 0x61, 0x74, 0x75, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x05, 0x00,
  0x0b, 0x00, 0x41, 0x76, 0x61, 0x00, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x43, 0x65,
  0x70, 0x68, 0x61, 0x6c, 0x6f, 0x70, 0x68, 0x75, 0x73, 0x20, 0x6a, 0x65,
  0x6e, 0x74, 0x69, 0x6e, 0x6b, 0x69, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0d, 0x00,
  0x0c, 0x00, 0x41, 0x78, 0x65, 0x6c, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x48, 0x69,
  0x70, 0x70, 0x6f, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x75, 0x73, 0x20, 0x61,
  0x6e, 0x74, 0x69, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x4d, 0x0b, 0x00,
  0x0d, 0x00, 0x41, 0x79, 0x61, 0x6e, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x47, 0x61,
  0x7a, 0x65, 0x6c, 0x6c, 0x61, 0x20, 0x63, 0x75, 0x76, 0x69, 0x65, 0x72,
  0x69, 0x00, 0x69, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x53, 0x0c, 0x00,
  0x0e, 0x00, 0x42, 0x72, 0x61, 0x64, 0x6c, 0x65, 0x79, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x42, 0x75,
  0x62, 0x61, 0x6c, 0x75, 0x73, 0x20, 0x6d, 0x69, 0x6e, 0x64, 0x6f, 0x72,
  0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x58, 0x04, 0x00,
  0x0f, 0x00, 0x42, 0x72, 0x65, 0x6e, 0x64, 0x61, 0x6e, 0x00, 0x00, 0x00,
  0x04, 0x00, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x74, 0x01, 0x42, 0x6f,
  0x73, 0x20, 0x67, 0x61, 0x75, 0x72, 0x75, 0x73, 0x00, 0x64, 0x6f, 0x72,
  0x65, 0x6e, 0x73, 0x69, 0x73, 0x00, 0x73, 0x69, 0x73, 0x00, 0x00, 0x00,
  0x5c, 0x3f, 0x1b, 0x00, 0x5c, 0x4f, 0x1b, 0x00, 0x5c, 0x58, 0x01, 0x00
};
unsigned int animals_dat_len = 900;
#include <stdio.h>
#include <string.h>
#include <ctype.h>

struct animal {
    short int id;
    char name[20];
    char species[35];
    char size;
    short int age;
};

static void debris_field(const char *tag, const char *field, size_t length)
{
    size_t nomlen = strlen(field);
    int count = 0;
    for (size_t i = nomlen; i < length; i++)
    {
        if (field[i] != '\0')
        {
            if (count == 0)
                printf("%8s (%2zu = %-20s) has debris:\n        ", tag, nomlen, field);
            count++;
            unsigned char u = field[i];
            if (isprint(u))
                putchar(u);
            else
                printf("\\x%.2X", u);
        }
    }
    if (count != 0)
        putchar('\n');
}

static void report_debris(const struct animal *info)
{
    debris_field("name", info->name, sizeof(info->name));
    debris_field("species", info->species, sizeof(info->species));
}

static void choice2(FILE *infile, int noisy)
{
    struct animal info;
    while (fread(&info, sizeof(info), 1, infile) == 1)
    {
        if (strcmp(info.name, "unknown") == 0)
        {
            printf("Deleted: %2d %20s %30s %c %2d\n", info.id, info.name, info.species, info.size, info.age);
        }
        else
        {
            printf("Current: %2d %20s %30s %c %2d\n", info.id, info.name, info.species, info.size, info.age);
        }
        if (noisy)
            report_debris(&info);
    }
}

int main(int argc, char **argv)
{
    int noisy = 0;
    if (argc > 1 && argv[argc] == 0)    // Use argv
        noisy = 1;
    choice2(stdin, noisy);
    return 0;
}
#include <stdio.h>

/* consts for max name/type, animals array, characters for buf */
enum { MAXNT = 20, MAXA = 128, MAXC = 512 };

typedef struct {
    int id,
        age;
    char name[MAXNT],
        type[MAXNT],
        size;
} animal;

int main (int argc, char **argv) {

    int n = 0;                              /* array index */
    char buf[MAXC] = "";                    /* line buffer */
    animal animals[MAXA] = {{ .id = 0 }};   /* animals array */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (n < MAXA && fgets (buf, MAXC, fp)) { /* read each line */
        /* parse animal data from line and validate conversion */
        if (sscanf (buf, "%d, %19[^,], %19[^,], %c, %d",
                    &animals[n].id, animals[n].name, animals[n].type, 
                    &animals[n].size, &animals[n].age) == 5)
            n++;    /* increment array index on successful conversion */
    }
    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    /* do what you need with data (printing here) */
    for (int i = 0; i < n; i++)
        printf ("%3d    %-20s  %-20s  %c  %3d\n", 
                animals[i].id, animals[i].name, animals[i].type, 
                animals[i].size, animals[i].age);

    return 0;
}
$ ./bin/animals <dat/animals.dat
  1    Allegra               Pseudois nayaur       S    5
  2    unknown               Ailurus fulgens       X   10
  3    Athena                Moschus fuscus        X    2
$ hexdump -Cv dat/animals.bin.dat
00000000  01 00 41 62 69 67 61 69  6c 00 00 00 04 00 00 00  |..Abigail.......|
00000010  74 01 00 00 74 01 43 61  70 72 69 63 6f 72 6e 69  |t...t.Capricorni|
00000020  73 20 73 75 6d 61 74 72  61 65 6e 73 69 73 00 00  |s sumatraensis..|
00000030  5c 3f 1b 00 5c 4f 1b 00  5c 53 08 00 02 00 75 6e  |\?..\O..\S....un|
00000040  6b 6e 6f 77 6e 00 00 00  04 00 00 00 74 01 00 00  |known.......t...|
00000050  74 01 4f 72 79 78 20 6c  65 75 63 6f 72 79 78 00  |t.Oryx leucoryx.|
00000060  6d 61 74 72 61 65 6e 73  69 73 00 00 5c 3f 1b 00  |matraensis..\?..|
00000070  5c 4f 1b 00 5c 4d 0c 00  03 00 41 64 72 69 61 6e  |\O..\M....Adrian|
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>

/* consts for max name, type, record size, max animals to read */
enum { MAXN = 20, MAXT = 35, RECSZ = 60, MAXA = 128 };

typedef struct {
    uint16_t id,
            age;
    char name[MAXN],
        type[MAXT],
        size;
} animal;

int main (int argc, char **argv) {

    int n = 0;                              /* array index */
    animal animals[MAXA] = {{ .id = 0 }};   /* animals array */
    FILE *fp = argc > 1 ? fopen (argv[1], "rb") : stdin;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (n < MAXA) {      /* read up to MAXA animal records */
        uint8_t rec[RECSZ] = "",            /* record buffer */
                size = 0,                   /* size of member */
                offset = 0;                 /* offset in record */

        if (fread (rec, 1, RECSZ, fp) != RECSZ) /* read/validate rec */
            break;

        size = sizeof animals[n].id;        /* get id size */
        memcpy (&animals[n].id, rec, size); /* copy from rec to id */
        offset += size;                     /* add size to rec offset */

        size = sizeof animals[n].name;      /* repeat for each member */
        memcpy (animals[n].name, rec + offset, size);
        offset += size;

        size = sizeof animals[n].type;
        memcpy (animals[n].type, rec + offset, size);
        offset += size;

        size = sizeof animals[n].size;
        memcpy (&animals[n].size, rec + offset, size);
        offset += size;

        size = sizeof animals[n].age;
        memcpy (&animals[n].age, rec + offset, size);

        n++;    /* increment array index after copy */
    }
    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    /* do what you need with data (printing here) */
    for (int i = 0; i < n; i++)
        printf ("%3" PRIu16 "    %-20s  %-35s  %c  %3" PRIu16 "\n",
                animals[i].id, animals[i].name, animals[i].type,
                animals[i].size, animals[i].age);

    return 0;
}
$ ./bin/animals_bin dat/animals.bin.dat
  1    Abigail               Capricornis sumatraensis             S    8
  2    unknown               Oryx leucoryx                        M   12
  3    Adrian                Cephalophus dorsalis                 L   16
  4    Ahmed                 Naemorhedus griseus                  L   10
  5    Aidan                 Naemorhedus caudatus                 X    9
  6    Allegra               Pseudois nayaur                      S    5
  7    Amela                 Cerdocyon thous                      M   11
  8    unknown               Capra falconeri                      M    1
  9    Anjolie               Ailurus fulgens                      L   10
 10    Athena                Moschus fuscus                       S    5
 11    Ava                   Cephalophus jentinki                 M   13
 12    Axel                  Hippocamelus antisensis              M   11
 13    Ayanna                Gazella cuvieri                      S   12
 14    Bradley               Bubalus mindorensis                  X    4
 15    Brendan               Bos gaurus                           X    1