C primer plus (第六版)第十一章 编程练习第11题
题目:
11.编写⼀个程序,读⼊10个字符串或者读到EOF时停⽌。该程序为⽤⼾提供⼀个有5个选项的菜单:打印源字符串列表、以ASCII中的顺序打印字符串、按⻓度递增顺序打印字符串、按字符串中第1个单词的⻓度打印字符串、退出。菜单可以循环显⽰,除⾮⽤⼾选择退出选项。当然,该程序要能真正完成菜单中各选项的功能。
分析:
11题更像是一个综合性练习题,题目中的4个选项功能肯定是通过函数实现,我还是通过AI帮忙修正编程中的函数的问题才完成题目,具体思路见程序中的注释。
程序:
/*
题目11.编写⼀个程序,读⼊10个字符串或者读到EOF时停⽌。该程序为⽤⼾提供⼀个
有5个选项的菜单:打印源字符串列表、以ASCII中的顺序打印字符串、按⻓度递增顺序打
印字符串、按字符串中第1个单词的⻓度打印字符串、退出。菜单可以循环显⽰,除⾮⽤
⼾选择退出选项。当然,该程序要能真正完成菜单中各选项的功能。
-------------------------------------------------------------------*/
/*思路:
1. 读入10个字符串,读到10个数量或者EOF时停止读取,需要有字符串读取中断退出逻辑。
2. 显示菜单,提示用户进行选择,需建立菜单打印函数,便于反复调用并在屏幕中显示菜单。
3. 用switch case语句建立菜单选择。
4. 选项1,打印源字符串列表,按照输入时的字符串顺序打印,需要复测是否正确建立字符串数组;
5. 选项2,以字符串中第一个字符的ASCII字母表顺序打印字符串,指针排序;
6. 选项3,以字符串长度递增的顺序打印字符串,strlen()函数,指针排序;
7. 选项4,按照字符串中第一个单词的长度递增打印字符串,首单词判断函数+指针排序
8. 选项5,退出程序。
-------------------------------------------------------------------*/#include <stdio.h>
#include <string.h>#define LIM 10 //指针数组限最大10组
#define SIZE 50 //每个字符串限50个字符void menu_show(void); //菜单显示函数
void prtstr_orig(char st[][SIZE], int n); //原数组顺序显示函数
void prtstr_ascii(char st[][SIZE], int n); //按ASCII顺序显示函数
void prtstr_length_rise(char st[][SIZE], int n); //按数组长度顺序显示函数
void prtstr_length_firstword(char st[][SIZE], int n); //按首单词长度顺序显示函数
char *s_gets(char * st, int n);
int first_word_len(const char *str); // 计算首单词长度(遇到空格或结束符为止) int main()
{int count = 0;int choose;char str_input[LIM][SIZE];char temp[SIZE];printf("Please enter up to %d strings.\n", LIM);while ( count < LIM ){if (s_gets(temp, SIZE) == NULL) // 处理输入失败(如Ctrl+Z)break;if (temp[0] == '\0') // 空字符串退出break;strcpy(str_input[count], temp);count++;}// printf("%d\n",count); //仅用于前期测试menu_show();while (1) // 无限循环,仅通过case 5退出{ printf("Enter your choice: ");int ret = scanf("%d", &choose);// 处理输入错误(非数字)if (ret != 1) {puts("Invalid input! Please enter a number (1-5).");// 清空缓冲区的错误输入while (getchar() != '\n');continue;}switch (choose){case 1:puts("String show as original order:");prtstr_orig(str_input, count);menu_show();break;case 2:puts("Strings show by ASCII order of first character:");prtstr_ascii(str_input, count);menu_show();break;case 3:puts("Strings show by string size in rise order:");prtstr_length_rise(str_input, count);menu_show();break;case 4:puts("Strings show by first word's size in rise order:");prtstr_length_firstword(str_input, count);menu_show();break;case 5:puts("Quit program.");return 0; // 退出程序default:puts("Invalid choice! Please enter 1-5.");break;} }return 0;
}int first_word_len(const char *str) // 计算首单词长度(遇到空格或结束符为止)
{int len = 0;while (*str != ' ' && *str != '\0') {len++;str++;}return len;
}void prtstr_length_firstword(char st[][SIZE], int n)
{char * temp;char * ptstr[LIM];for (int i = 0; i < n; i++){ptstr[i] = st[i];}for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) {if (first_word_len(ptstr[j]) > first_word_len(ptstr[j + 1])) {// 交换指针(不移动字符串本身)temp = ptstr[j];ptstr[j] = ptstr[j + 1];ptstr[j + 1] = temp;}}}for ( int i = 0; i < n; i++){fputs(ptstr[i], stdout);putchar('\n');}
}void prtstr_length_rise(char st[][SIZE], int n)
{char * temp;char * ptstr[LIM];for (int i = 0; i < n; i++){ptstr[i] = st[i];}for (int i = 0; i < n - 1; i++) { // 控制排序轮数(n个元素需n-1轮)// 内层循环:每轮比较到未排序的最后一个元素for (int j = 0; j < n - 1 - i; j++) {if (strlen(ptstr[j]) > strlen(ptstr[j + 1])) {// 交换指针(不移动字符串本身)temp = ptstr[j];ptstr[j] = ptstr[j + 1];ptstr[j + 1] = temp;}}}for ( int i = 0; i < n; i++){fputs(ptstr[i], stdout);putchar('\n');}
}void prtstr_ascii(char st[][SIZE], int n)
{char * temp;char * ptstr[LIM];for (int i = 0; i < n; i++){ptstr[i] = st[i];}for (int i = 0; i < n - 1; i++) { // 控制排序轮数(n个元素需n-1轮)// 内层循环:每轮比较到未排序的最后一个元素for (int j = 0; j < n - 1 - i; j++) {// 比较相邻两个字符串的首字符if (ptstr[j][0] > ptstr[j + 1][0]) {// 交换指针(不移动字符串本身)temp = ptstr[j];ptstr[j] = ptstr[j + 1];ptstr[j + 1] = temp;}}}for ( int i = 0; i < n; i++){fputs(ptstr[i], stdout);putchar('\n');}
}void prtstr_orig(char st[][SIZE], int n)
{int i = 0;for ( i = 0; i < n; i++){fputs(st[i], stdout);putchar('\n');}
}char * s_gets(char * st, int n)
{char * ret_val;int i = 0;ret_val = fgets(st, n, stdin);if (ret_val){while (st[i] != '\n' && st[i] != '\0')i++;if (st[i] == '\n')st[i] = '\0';elsewhile (getchar() != '\n')continue;}return ret_val;
}void menu_show(void)
{puts("MENU (enter 1 ~ 5 to choose options):");puts("1. Print strings by original list order.");puts("2. Print strings by ASCII order of first character.");puts("3. Print strings by string size in rise order.");puts("4. Print strings by first word's size in rise order.");puts("5. Quit.");
}
