02-示例问题_创建图书目录
14.1 示例问题:创建图书目录
Gwen Glenn要打印一份图书目录。她想打印每本书的各种信息:书名、作者、出版社、版权日期、页数、册数和价格。其中的一些项目(如,书名)可以存储在字符数组中,其他项目需要一个 int
数组或 float
数组。用7个不同的数组分别记录每一项比较繁琐,尤其是Gwen还想创建多份列表:一份按书名排序、一份按作者排序、一份按价格排序等。如果能把图书目录的信息都包含在一个数组里更好,其中每个元素包含一本书的相关信息。
因此,Gwen需要一种即能包含字符串又能包含数字的数据形式,而且还要保持各信息的独立。C结构就满足这种情况下的需求。我们通过一个示例演示如何创建和使用数组。但是,示例进行了一些限制。第一,该程序示例演示的书目只包含书名、作者和价格。第二,只有一本书的数目。当然,别忘了这只是进行了限制,我们在后面将扩展该程序。请看程序清单14.1及其输出,然后阅读后面的一些要点。
程序清单14.1 book.c
程序
//* book.c -- 一本书的图书目录 */
#include <stdio.h>
#include <string.h>
char * s_gets(char * st, int n);
#define MAXTITL 41 /* 书名的最大长度 + 1 */
#define MAXAUTL 31 /* 作者姓名的最大长度 + 1*/
struct book { /* 结构模版:标记是 book */
char title[MAXTITL];
char author[MAXAUTL];
float value;
}; /* 结构模版结束 */
int main(void)
{
struct book library; /* 把 library 声明为一个 book 类型的变量 */
printf("Please enter the book title.\n");
s_gets(library.title, MAXTITL); /* 访问title部分*/
printf("Now enter the author.\n");
s_gets(library.author, MAXAUTL);
printf("Now enter the value.\n");
scanf("%f", &library.value);
printf("%s by %s: $%.2f\n", library.title,
library.author, library.value);
printf("%s: \"%s\" ($%.2f)\n", library.author,
library.title, library.value);
printf("Done.\n");
return 0;
}
char * s_gets(char * st, int n)
{
char * ret_val;
char * find;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
find = strchr(st, '\n'); // 查找换行符
if (find) // 如果地址不是 NULL,
*find = '\0'; // 在此处放置一个空字符
else
while (getchar() != '\n')
continue; //处理输入行中剩余的字符
}
return ret_val;
}
我们使用前面章节中介绍的 s_gets()
函数去掉 fgets()
存储在字符串中的换行符。下面是该例的一个运行示例:
Please enter the book title.
Chicken of the Andes
Now enter the author.
Disma Lapoult
Now enter the value.
29.99
Chicken of the Andes by Disma Lapoult: $29.99
Disma Lapoult: "Chicken of the Andes" ($29.99)
Done.
程序清单14.1中创建的结构有3部分,每个部分都称为成员(member)或字段(field)。这 3
部分中,一部分存储书名,一部分存储作者名,一部分存储价格。下面是必须掌握的3个技巧:
- 为结构建立一个格式或样式;
- 声明一个适合该样式的变量;
- 访问结构变量的各个部分。