题目
为了说明实际应用中数组和结构是如何嵌套的,现在开发一个相对大一点程序,此程序用来维护仓库存储的零件信息的数据库。程序围绕一个结构数组构建,且每个结构包含以下信息:零件的编号、名称以及数量。
1)添加新零件编号、名称和初始现货数量
2)给定零件编号,显示出零件的名称和当前的现货数量
3)给定零件编号,改变现有的零件数量
4)显示列出数组库中全部信息的表格
5)终止程序的执行
程序包含三个文件:inventory.c、readline.c、read_line.h
程序
//Maintains a parts database (array version)
#include "readline.h"
#include <stdio.h>
#define NAME_LEN 25
#define MAX_PARTS 100
struct part {
int number;
char name[NAME_LEN + 1];
int on_hand;
}inventory[MAX_PARTS];
int num_parts = 0;//存储当前零件数量
int find_part(int number);
void insert(void);
void search(void);
void update(void);
void print(void);
int main(void)
{
char code;
for (;;) {
printf("Enter operation code: ");
scanf(" %c", &code);//%c允许scanf函数再度入操作码之前跳过空白字符(前一行输入行末尾的换行符)
while (getchar() != '\n')
;
switch (code) {
case 'i':insert();
break;
case 's':search();
break;
case 'u':update();
break;
case 'p':print();
break;
case 'q':return 0;
default:printf("Illegal code\n");
}
printf("\n");
}
}
//find_part:在结构数组中查找序号,然后返回下标
int find_part(int number)
{
int i;
for (i = 0; i < num_parts; i++)
if (inventory[i].number == number)
return i;
return -1;//用于子函数结尾,表示该函数失败
}
//insert:插入数据库,如果满了返回错误信息
void insert(void)
{
int part_number;
if (num_parts == MAX_PARTS) {
printf("Database is full; can't add more parts.\n");
return;//数据库已满显示出错信息
}
printf("Enter part number: ");
scanf("%d", &part_number);
if (find_part(part_number) >= 0) {
printf("Part alreadly exists.\n");
return;
}
inventory[num_parts].number = part_number;
printf("Enter part name: ");
read_line(inventory[num_parts].name, NAME_LEN);
printf("Enter quantity on hand: ");
scanf("%d", &inventory[num_parts].on_hand);
num_parts++;
}
//search:查找零件序号
void search(void)
{
int i, number;
printf("Enter part number: ");
scanf("%d", &number);
i = find_part(number);
if (i >= 0) {
printf("Part name: %s\n", inventory[i].name);
printf("Quantity on hand: %d\n", inventory[i].on_hand);
}
else
printf("Part not found.\n");
}
//update:更新数据库
void update(void)
{
int i, number, change;
printf("Enter part number: ");
scanf("%d", &number);
i = find_part(number);
if (i >= 0) {
printf("Enter change in quantity on hand: ");
scanf("%d", &change);
inventory[i].on_hand += change;
}
else
printf("Part not found.\n");
}
//print:显示数据库中序号、名称、数量
void print(void) {
int i;
printf("Part Number Part Name "
"Quantity on Hand\n");
for (i = 0; i < num_parts; i++)
printf("%7d %-25s%11d\n", inventory[i].number,
inventory[i].name, inventory[i].on_hand);
}
readline.c文件
// read_line函数的定义
#include <ctype.h>
#include <stdio.h>
#include "readline.h"
int read_line(char str[], int n)
{
int ch, i = 0;
while (isspace(ch = getchar())) //isspace用于检查参数ch是否为空格
;
while (ch != '\n'&&ch != EOF) {
if (i < n)
str[i++] = ch;
ch = getchar();//注意:getchar函数实际上返回的是int类型值,当读到末尾时,返回值为EOF
}
str[i] = '\0';
return i;
}
头文件
#ifndef READLINE_H
#define READLINE_H
int read_line(char str[], int n);
#endif //PCH_H
重点
具体地每个子函数理解较为简单,需要注意的是:不同函数访问同一变量可以将变量设置为外部变量(尽可能少),或者把变量声明在main函数内,然后把他们作为实际参数传递给函数(更好),因为外部比那里对所有函数都是可见的,不仅难维护还会产生误导。头文件等的编译,外部独立函数怎么编译。