1. 编写程序用来要求用户录入国际电话区号,然后在数组country_codes中查找它(见16.3节)。如果找到对应的区号,程序需要显示相应的国家名称,否则显示出错消息。
#include <stdio.h>
#define ARRAY_LEN(x) ((int) (sizeof((x)) / sizeof((x)[0])))
const struct {
char *country;
int code;
} country_codes[] =
{{"Argentina", 54}, {"Bangladesh", 889},
{"Brazil", 55}, {"Burma (Myanmar)", 95},
{"China", 86}, {"Colombia", 57},
{"Congo, Dem. Rep. of", 243}, {"Egypt", 20},
{"Ethiopia", 251}, {"France", 33},
{"Germany", 49}, {"India", 91},
{"Indonesia", 62}, {"Iran", 98},
{"Italy", 39}, {"Japan", 81},
{"Mexico", 52}, {"Nigeria", 234},
{"Pakistan", 92}, {"Philippines", 63},
{"Poland", 48}, {"Russia", 7},
{"South Africa", 27}, {"South Korea", 82},
{"Spain", 34}, {"Sudan", 249},
{"Thailand", 66}, {"Turkey", 90},
{"Ukraine", 380}, {"United Kingdom", 44},
{"United States", 1}, {"Vietnam", 84}};
int main(void) {
int code, i;
printf("Enter an international dialing code: ");
scanf("%d", &code);
for (i = 0; i < ARRAY_LEN(country_codes); i++) {
if (country_codes[i].code == code) {
printf("%d is the code for %s.\n", code, country_codes[i].country);
return 0;
}
}
printf("Error: %d is not a valid country code.\n", code);
return 0;
}
2. 修改16.3节的inventory.c程序,使p(显示)操作可以按零件编号的顺序显示零件。
inventory.c
#include <stdio.h> #include "inventory.h" #include "readline.h" #include "quicksort.h" int num_parts = 0; int find_part(int number); void insert(void); void search(void); void update(void); void print(void); /* * main: Prompts the user to enter an operation code, then calls a function to * perform the requested action. Repeats until the user enters the command * 'q'. Prints an error message if the user enters an illegal code. */ int main(void) { char code; for (;;) { printf("Enter operation code: "); scanf(" %c", &code); 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: Looks up a part number in the inventory array. Returns the array * index if the part number is found; otherwise returns -1. */ int find_part(int number) { int i; for (i = 0; i < num_parts; i++) if (inventory[i].number == number) return i; return -1; } /* * insert: Prompts the user for information about a new part and then inserts * the part into the database. Prints an error message and returns * prematurely if the part already exists or the database is full. */ 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 already 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: Prompts the user to enter a part number, then looks up the part in * the database. If the part exists, prints the name and quantity on * hand; if not, prints an error message. */ 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: Prompts the user to enter a part number. Prints an error message if * the part doesn't exist; otherwise, prompts the user to enter change * in quantity on hand and updates the database. */ 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: Prints a listing of all parts in the database, showing the part * number, part name and quantity on hand. Parts are printed, sorted by * their part number. */ void print(void) { int i; quicksort(inventory, 0, num_parts-1); 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); }
inventory.h
#ifndef INVENTORY_H #define INVENTORY_H #define NAME_LEN 25 #define MAX_PARTS 100 struct part { int number; char name[NAME_LEN+1]; int on_hand; } inventory[MAX_PARTS]; #endif
quicksort.c
#include "quicksort.h" void quicksort(struct part a[], int low, int high) { int middle; if (low >= high) return; middle = split(a, low, high); quicksort(a, low, middle - 1); quicksort(a, middle + 1, high); } int split(struct part a[], int low, int high) { struct part part_element = a[low]; for (;;) { while (low < high && part_element.number <= a[high].number) high--; if (low >= high) break; a[low++] = a[high]; while (low < high && a[low].number <= part_element.number) low++; if (low >= high) break; a[high--] = a[low]; } a[high] = part_element; return high; }
quicksort.h
/* quicksort, edited for struct part */ #ifndef QUICKSORT_H #define QUICKSORT_H #include "inventory.h" void quicksort(struct part a[], int low, int high); int split(struct part a[], int low, int high); #endif
readline.c
#include <ctype.h> /* isspace */ #include <stdio.h> #include "readline.h" int read_line(char str[], int n) { int c, i = 0; while (isspace(c = getchar())) ; while (c != '\n' && c != EOF) { if (i < n) str[i++] = c; c = getchar(); } str[i] = '\0'; return i; }
readline.h
#ifndef READLINE_H #define READLINE_H /* read_line: Skips leading whitespace characters, then reads the remainder of * the input line and stores it in str. Truncates the line if its * length exceeds n. Returns the number of characters stores. */ int read_line(char str[], int n); #endif
3. 修改16.3节的inventory.c程序,使inventory和num_parts局部于main函数。
inventory.c
#include <stdio.h> #include "inventory.h" #include "readline.h" #include "quicksort.h" int find_part(const struct part inventory[], int num_parts, int number); void insert(struct part inventory[], int *num_parts); void search(const struct part inventory[], int num_parts); void update(struct part inventory[], int num_parts); void print(struct part inventory[], int num_parts); /* * main: Prompts the user to enter an operation code, then calls a function to * perform the requested action. Repeats until the user enters the command * 'q'. Prints an error message if the user enters an illegal code. */ int main(void) { int num_parts = 0; struct part inventory[MAX_PARTS]; char code; for (;;) { printf("Enter operation code: "); scanf(" %c", &code); while (getchar() != '\n') ; switch(code) { case 'i': insert(inventory, &num_parts); break; case 's': search(inventory, num_parts); break; case 'u': update(inventory, num_parts); break; case 'p': print(inventory, num_parts); break; case 'q': return 0; default: printf("Illegal code\n"); } printf("\n"); } } /* * find_part: Looks up a part number in the inventory array. Returns the array * index if the part number is found; otherwise returns -1. */ int find_part(const struct part inventory[], int num_parts, int number) { int i; for (i = 0; i < num_parts; i++) if (inventory[i].number == number) return i; return -1; } /* * insert: Prompts the user for information about a new part and then inserts * the part into the database. Prints an error message and returns * prematurely if the part already exists or the database is full. */ void insert(struct part inventory[], int *num_parts) { 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(inventory, *num_parts, part_number) >= 0) { printf("Part already 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: Prompts the user to enter a part number, then looks up the part in * the database. If the part exists, prints the name and quantity on * hand; if not, prints an error message. */ void search(const struct part inventory[], int num_parts) { int i, number; printf("Enter part number: "); scanf("%d", &number); i = find_part(inventory, num_parts, 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: Prompts the user to enter a part number. Prints an error message if * the part doesn't exist; otherwise, prompts the user to enter change * in quantity on hand and updates the database. */ void update(struct part inventory[], int num_parts) { int i, number, change; printf("Enter part number: "); scanf("%d", &number); i = find_part(inventory, num_parts, 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: Prints a listing of all parts in the database, showing the part * number, part name and quantity on hand. Parts are printed, sorted by * their part number. */ void print(struct part inventory[], int num_parts) { int i; quicksort(inventory, 0, num_parts-1); 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); }
inventory.h
#ifndef INVENTORY_H #define INVENTORY_H #define NAME_LEN 25 #define MAX_PARTS 100 struct part { int number; char name[NAME_LEN+1]; int on_hand; }; #endif
4. 修改16.3节的inventory.c程序,为结构part添加成员price。insert函数应该要求用户录入新商品的价格。serach函数和print函数应该显示价格。添加一条新的命令,允许用户修改零件的价格。
#include <stdio.h>
#include "inventory.h"
#include "readline.h"
#include "quicksort.h"
int find_part(const struct part inventory[], int num_parts, int number);
void insert(struct part inventory[], int *num_parts);
void search(const struct part inventory[], int num_parts);
void update(struct part inventory[], int num_parts);
void print(struct part inventory[], int num_parts);
void change_price(struct part inventory[], int num_parts);
/*
* main: Prompts the user to enter an operation code, then calls a function to
* perform the requested action. Repeats until the user enters the command
* 'q'. Prints an error message if the user enters an illegal code.
*/
int main(void) {
int num_parts = 0;
struct part inventory[MAX_PARTS];
char code;
for (;;) {
printf("Enter operation code: ");
scanf(" %c", &code);
while (getchar() != '\n')
;
switch(code) {
case 'i': insert(inventory, &num_parts);
break;
case 's': search(inventory, num_parts);
break;
case 'u': update(inventory, num_parts);
break;
case 'p': print(inventory, num_parts);
break;
case 'c': change_price(inventory, num_parts);
break;
case 'q': return 0;
default: printf("Illegal code\n");
}
printf("\n");
}
}
/*
* find_part: Looks up a part number in the inventory array. Returns the array
* index if the part number is found; otherwise returns -1.
*/
int find_part(const struct part inventory[], int num_parts, int number) {
int i;
for (i = 0; i < num_parts; i++)
if (inventory[i].number == number)
return i;
return -1;
}
/*
* insert: Prompts the user for information about a new part and then inserts
* the part into the database. Prints an error message and returns
* prematurely if the part already exists or the database is full.
*/
void insert(struct part inventory[], int *num_parts) {
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(inventory, *num_parts, part_number) >= 0) {
printf("Part already 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);
printf("Enter price: ");
scanf("%lf", &inventory[*num_parts].price);
(*num_parts)++;
}
/*
* search: Prompts the user to enter a part number, then looks up the part in
* the database. If the part exists, prints the name and quantity on
* hand; if not, prints an error message.
*/
void search(const struct part inventory[], int num_parts) {
int i, number;
printf("Enter part number: ");
scanf("%d", &number);
i = find_part(inventory, num_parts, number);
if (i >= 0) {
printf("Part name: %s\n", inventory[i].name);
printf("Quantity on hand: %d\n", inventory[i].on_hand);
printf("Price: $%.2f\n", inventory[i].price);
} else
printf("Part not found.\n");
}
/*
* update: Prompts the user to enter a part number. Prints an error message if
* the part doesn't exist; otherwise, prompts the user to enter change
* in quantity on hand and updates the database.
*/
void update(struct part inventory[], int num_parts) {
int i, number, change;
printf("Enter part number: ");
scanf("%d", &number);
i = find_part(inventory, num_parts, 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: Prints a listing of all parts in the database, showing the part
* number, part name and quantity on hand. Parts are printed, sorted by
* their part number.
*/
void print(struct part inventory[], int num_parts) {
int i;
quicksort(inventory, 0, num_parts-1);
printf("Part Number Part Name "
"Quantity on Hand Price\n");
for (i = 0; i < num_parts; i++)
printf("%7d %-25s%11d $%7.2f\n", inventory[i].number,
inventory[i].name, inventory[i].on_hand, inventory[i].price);
}
/*
* change_price: Prompts the user to enter a part number. Prints an error
* message if the part doesn't exist; otherwise, prompts the user
* to enter new price and updates the database.
*/
void change_price(struct part inventory[], int num_parts) {
int i, number;
printf("Enter part number: ");
scanf("%d", &number);
i = find_part(inventory, num_parts, number);
if (i >= 0) {
printf("Enter new price: ");
scanf("%lf", &inventory[i].price);
} else
printf("Part not found.\n");
}
5. 修改第5章的编程题8,以便用一个单独的数组存储时间。数组的元素都是结构,每个结构包含起飞时间和对应的抵达时间。(时间都是整数,表示从午夜开始的分钟数。)程序用一个循环从数组中搜索与用户输入的时间最接近的起飞时间。
#include <stdio.h>
#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))
const struct flight {
int departure;
int arrival;
} times[] = {
{480, 616}, {583, 712}, { 679, 811}, {767, 900},
{840, 968}, {945, 1075}, {1140, 1280}, {1305, 1438}
};
void print(const struct flight time);
int main(void) {
int user_time, hour, i, minute;
printf("Enter a 24-hour time: ");
scanf("%d :%d", &hour, &minute);
user_time = hour * 60 + minute;
printf("Closest departure time is ");
for (i = 0; i < ARRAY_LEN(times) - 1; i++) {
if (user_time <= times[i].departure +
(times[i+1].departure - times[i].departure) / 2) {
print(times[i]);
return 0;
}
}
i++;
print(times[i]);
return 0;
}
void print(const struct flight time) {
printf("%d:%.2d %c.m., arriving at %d:%.2d %c.m.\n",
time.departure/60 > 12 ? time.departure/60 - 12 : time.departure/60,
time.departure%60, time.departure > 719 ? 'p' : 'a',
time.arrival/60 > 12 ? time.arrival/60 - 12 : time.arrival/60,
time.arrival%60, time.arrival > 719 ? 'p' : 'a');
}
6. 修改第5章的编程题9,以便用户输入的日期都存储在一个date结构(见练习题5)中。把练习题5中的compare_dates函数集成到你的程序中。
#include <stdio.h>
struct date {
int year;
int month;
int day;
};
int day_of_year(struct date d);
int compare_dates(struct date d1, struct date d2);
int main(void) {
struct date d1, d2;
int comparison;
printf("Enter first date (mm/dd/yy): ");
scanf("%d /%d /%d", &d1.month, &d1.day, &d1.year);
printf("Enter second date (mm/dd/yy): ");
scanf("%d /%d /%d", &d2.month, &d2.day, &d2.year);
comparison = compare_dates(d1, d2);
if (comparison > 0)
printf("%d/%d/%d comes before %d/%d/%d\n",
d1.month, d1.day, d1.year, d2.month, d2.day, d2.year);
else if (comparison < 0)
printf("%d/%d/%d comes before %d/%d/%d\n",
d2.month, d2.day, d2.year, d1.month, d1.day, d1.year);
else
printf("%d/%d/%d and %d/%d/%d are equal\n",
d1.month, d1.day, d1.year, d2.month, d2.day, d2.year);
return 0;
}
int day_of_year(struct date d) {
int res = 0, i;
const int days_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (d.month > 1 && ((d.year % 4 == 0 && d.year % 100 != 0)
|| d.year % 400 == 0))
res++;
for (i = 0; i < d.month; i++)
res += days_month[i];
return res + d.day;
}
int compare_dates(struct date d1, struct date d2) {
int d1day = day_of_year(d1);
int d2day = day_of_year(d2);
if (d1day > d2day)
return -1;
else if (d1day < d2day)
return 1;
else
return 0;
}