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