mirror of
https://github.com/hairrrrr/C-CrashCourse.git
synced 2026-02-03 10:43:15 +08:00
4-19
This commit is contained in:
5
code/practise/17 指针的高级应用/01 显示一个月的提醒列表/readme.md
Normal file
5
code/practise/17 指针的高级应用/01 显示一个月的提醒列表/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
#### 程序:显示一个月的提醒列表
|
||||
|
||||
前面我们把字符串存储在二维数组中,但是这可能会浪费空间。后面的教学中我们设想使用指针数组存储字符串,让一维数组的每个元素都指向一个字符串字面量。如果数组元素是指向动态分配的字符串的指针,那么是可以实现我们的设想的。
|
||||
|
||||
下面的程序对之前的程序作了小部分修改,修改的地方后面用注释注明了。
|
||||
86
code/practise/17 指针的高级应用/01 显示一个月的提醒列表/reminder.c
Normal file
86
code/practise/17 指针的高级应用/01 显示一个月的提醒列表/reminder.c
Normal 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;
|
||||
}
|
||||
234
code/practise/17 指针的高级应用/02 维护零件数据库(链表)/inventory2.c
Normal file
234
code/practise/17 指针的高级应用/02 维护零件数据库(链表)/inventory2.c
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user