This commit is contained in:
hairrrrr
2020-04-19 01:06:17 +08:00
parent de4a7a1243
commit 76148c3a4f
3 changed files with 325 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
#### 程序:显示一个月的提醒列表
前面我们把字符串存储在二维数组中,但是这可能会浪费空间。后面的教学中我们设想使用指针数组存储字符串,让一维数组的每个元素都指向一个字符串字面量。如果数组元素是指向动态分配的字符串的指针,那么是可以实现我们的设想的。
下面的程序对之前的程序作了小部分修改,修改的地方后面用注释注明了。

View File

@@ -0,0 +1,86 @@
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_REMIND 50
#define MSG_LEN 100
int read_line(char str[], int read_num);
int main(void) {
char* reminders[MAX_REMIND]; // 存放提示的数组 // change
char day_str[3];//当前日期转换为字符串
char msg_str[MSG_LEN + 1]; //当前输入的提示消息
int day, num_remind = 0; // 日期和当前提示数
int i, j;
for (;;) {
if (num_remind == MAX_REMIND) {
printf("-- No space left --\n");
break;
}
printf("Enter day and reminder:");
scanf("%2d", &day); //每月的日期只用两个数表示即可,只读 2 个字段
if (day == 0)
break;
sprintf(day_str, "%2d", day); // 将 day 以 "%2d" 的格式写入 day_str 字符数组中。"%2d" 保证小于10的天占两位右对齐
read_line(msg_str, MSG_LEN);
// 寻找当前输入的提示应该放到提示数组的那个位置
for (i = 0; i < num_remind; i++) {
// 说明当前输入的日期应该排在此行前
if (strcmp(day_str, reminders[i]) < 0)
break;
}
// 将当前输入的提示插入到正确的位置
for (j = num_remind; j > i; j--) {
reminders[j] = reminders[j - 1]; // change
}
reminders[i] = (char*)malloc(sizeof(msg_str) + sizeof(day_str) + 1); // change
// change
if (reminders[i] == NULL) {
printf("-- No space left --\n");
break;
}
strcpy(reminders[i], day_str);
strcat(reminders[i], msg_str);// 刚好将 day_str 复制进去的空字符覆盖掉了
num_remind++;
}
printf("Day Reminder: \n");
for (i = 0; i < num_remind; i++)
printf("%s\n", reminders[i]);
return 0;
}
int read_line(char str[], int read_num) {
int ch, count = 0;
while ((ch = getchar()) != '\n') {
if (count < read_num) {
str[count++] = ch;
}
}
str[count] = '\0';
return count;
}

View File

@@ -0,0 +1,234 @@
#include<stdio.h>
#include<stdlib.h>
#include"readline.h"
#define NAME_LEN 20
typedef struct part {
int number;
char name[NAME_LEN + 1];
int on_hand;
struct part* next;
}part;
void menu();
part* find_part(part* head, int number);
void insert(part* head);
void search(part* head);
void update(part* head);
void print(part* head);
int main(void) {
char code = 'a';
part* head = (part*)malloc(sizeof(part));
head->next = NULL;
if (head == NULL) {
printf("Database establish failed\n");
exit(EXIT_SUCCESS);
}
menu();
for (;;) {
printf("Enter operation code: ");
scanf(" %c", &code);
while (getchar() != '\n') // skips to end of line
;
switch (code) {
case 'i': insert(head); break;
case 's': search(head); break;
case 'u': update(head); break;
case 'p': print(head); break;
case 'q': return 0;
default: printf("Illegal code.\n"); break;
}
}
return 0;
}
void menu() {
printf(" ==================================\n");
printf(" * *\n");
printf(" * i: insert *\n");
printf(" * s: search *\n");
printf(" * u: undate *\n");
printf(" * p: print *\n");
printf(" * q: quit *\n");
printf(" * *\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,return -1
*
***********************************************************/
part* find_part(part* head, int number) {
part* cur;
// 链表是按照编号升序排序的
for (cur = head->next; cur != NULL && cur->number > number;
cur = cur->next)
;
if (cur == NULL)
return NULL;
if (cur->number == number)
return cur;
}
/**********************************************************
*
* insert: 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(part* head) {
int part_number;
part* cur, * prev, *new_part;
printf("Enter part number: ");
scanf("%d", &part_number);
// 寻找 part_number 所应插入的位置,我们需要 cur 遍历链表,但是应该保留 cur 前面的结点 prev
// 退出循环条件cur == NULL 说明是头插或尾插
// cur->number > part_number 说明 输入的编号重复
// 应该在 cur 和 prev 之间插入新的零件 或 头插
for (cur = head->next, prev = NULL;cur != NULL && cur->number < part_number ;
prev = cur, cur = cur->next)
;
// 判断输入的编号是否于数据库中的现有重复
if (cur != NULL && cur->number == part_number) {
printf("Part already exists.\n");
return;
}
// 申请新结点
new_part = (part*)malloc(sizeof(part));
// 判断申请是否成功
if (new_part == NULL) {
printf("Database is full; can't add more parts.\n");
return;
}
new_part->number = part_number;
printf("Enter part name: ");
read_line(new_part->name, NAME_LEN);
printf("Enter quantity on hand: ");
scanf("%d", &new_part->on_hand);
// 插入的方式:
// 链表为空时:对 head 进行操作prev == NULL, cur == NULL
// 链表不为空:
// 头插:对 head 操作 (prev == NULL, cur != NULL)
// 尾插:对 prev 操作 (prev != NULL, cur == NULL)
// 普通位置插入:对 prev 操作(prev,cur 都不为 NULL)
new_part->next = cur;
if (prev == NULL)
head->next = new_part;
else
prev->next = new_part;
}
/************************************************************
*
* search: Look up a part by the number user enters.
* If the part exists, prints the name and quantity
* on hand;if not, print an error message.
*
************************************************************/
void search(part* head) {
int number;
part* trg;
printf("Enter part number: ");
scanf("%d", &number);
trg = find_part(head, number);
if (trg == NULL) {
printf("Part not found.\n");
return;
}
printf("Part name: %s\n", trg->name);
printf("Quantity on hand: %d\n", trg->on_hand);
}
/************************************************************
*
* update: Prompts user to enter a number.
* Print 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(part* head) {
int number, change;
part* trg;
printf("Enter part number: ");
scanf("%d", &number);
trg = find_part(head, number);
if (trg == NULL) {
printf("Part not found.\n");
return;
}
printf("Enter change in quantity on hand(- means minus): ");
scanf("%d", &change);
trg->on_hand += change;
}
/************************************************************
*
* print: Print a listing of all parts in the database,
* showing the part number,part name and quantity
* on hand.Parts are printed in the order in which
* they were entered into the database.
*
************************************************************/
void print(part* head) {
printf("Part Number Part Name Quantity on Hand\n");
for (part* cur = head->next; cur != NULL; cur = cur->next) {
printf("%6d%20s%15d\n", cur->number, cur->name, cur->on_hand);
}
}