C primer plus 第六版 第十一章 第十一题题 编程练习答案

版权声明:转载请注明来源~ https://blog.csdn.net/Lth_1571138383/article/details/85843765

Github地址:φ(>ω<*)这里这里。

/*
    编写一个程序,读入10个字符串或者读到EOF时停止。该程序为用户提供一个有5个选项的菜单
    1、打印源字符串列表; 
    2、以ASCII中的顺序打印字符串;
    3、按长度递增顺序打印字符串;
    4、按字符串中第一个单词的长度打印字符串
    5、退出。
    菜单可以循环显示,除非用户选择退出选项。
    (T▽T)我想要今晚写完练吉他 --2018.December.28
    德玛西亚————今天刚开工。。--2018.December.30
    今天外面走了四公里,感觉自己老了,感觉要猝死了啊。。还有代码没写完(T ^ T) --2018.December.31
    今天要完成它!!!! --2019.January.2nd
    一天一个函数,总有一天可以完成它。 -- 2019.January.3rd
    哈哈,今天完工了!!!!!! -- 2019.January.5th
*/
/*
    解题思路:首先,你们打开音乐播放器,搜索并播放 “朗格里格朗浪” 。(`・ω・´)
    我先建立基本的循环,先获取用户输入;然后switch来响应用户输入。
    具体请看各函数的定义部分,里面有讲解。函数原型这边如果写讲解,开头会很长,不好review代码。
*/
 

#include<stdio.h>
#include<string.h>

#define o 10
#define p 100

void del_n(char *p1[o]);	// 删除fgets()函数保存的换行符。

char menu(void);			// 菜单函数。

void print1(char *p1[o]);	// 菜单操作1:原样输出。

void print2(char *p1[o]);	// 菜单操作2:据ASCII码字母表顺序排序字符串。

void print3(char *p1[o]);	// 菜单操作3:顺序递增排序字符串。

void print4(char *p1[o]);   // 菜单操作4:按字符串中第一个单词的长度打印字符串。

int main(void)
{
	int i = 0;
	char chose = 0;
	char name[o][p] = {};
	char *p1[o];

	printf("Please input 10 string(Press Enter to continue):\n");

	// 获取输入操作,并把输入储存到 十个指向 char的指针。
	// 这么做参考书上 P359 的 stsrt()函数定义部分。 char *p[] 操作。
	// 使用该操作的好处:对于函数定义部分来说,构建的代码更清晰易懂,也更简洁优美。
	for(i = 0; i < o; i++)
	{
		fgets(name[i], p, stdin);

		p1[i] = name[i];  // 没问题。
	}

	putchar('\n');
	del_n(p1);

	// 菜单部分,调用函数响应用户输入。
	while(chose != 'q')
	{
		chose = menu();
		switch(chose)
		{
			case 'a':
				print1(p1);
				break;
			case 'b':
				print2(p1);
				break;
			case 'c':
				print3(p1);
				break;
			case 'd':
				print4(p1);
			case 'q':
				break;
			default:
				printf("\nError with code(Line 86)\n");
				break;
		}

		if(chose == 'q')
		{
			break;
		}

	}

	printf("Bye~\n");
	getchar();

	return 0;
}

char menu(void)
{
	// 本函数为菜单输出与return用户选项函数。
	int i = 0;
	char chose;

	while(i < 100)
	{
		putchar('*');
		i++;
	}

	i = 0;

	printf("\nThere are 5 features you can use:\n");

	printf("	a、打印源字符串列表;               "                          
	"b、以ASCII中的顺序打印字符串.\n");

	printf("	c、按长度递增顺序打印字符串;           "
	"d、按字符串中第一个单词的长度打印字符串.\n");

	printf("	q、退出。\n");
	
	while(i < 100)
	{
		putchar('*');
		i++;
	}

	i = 0;

	printf("\nNow, Please input your chose:\n");
	chose = getchar();
	fflush(stdin);

	return chose;
}

void print1(char *p1[o])
{
	// 本函数原样输出,这个就不多说了。。 
	printf("\n打印效果如下:\n");

	for(int i = 0; i < o; i++)
	{
		printf("%s\n", p1[i]);
	}

	printf("\nOver ~\n\n");

	return;
}

void print2(char *p1[o])
{
	// 本函数的核心部分--排序 参考了书 P359 的 stsrt()函数,使用了 char *p[10] 操作方式。
	// 该操作使代码的整体构建 简洁优美,清晰易懂。 这比我之前用 char(*p)[10] 的好多了。
	// char (*P)[10]的意思是声明一个指向数组的指针,该指针内含[10]个char元素值。
	// char *p[10]的意思是声明 一个内含10个元素的数组p, *表示p数组内含10个指针。 最后char让p数组内的指针都指向char。
	// *p[10]就像一个数组 p[10][],操作起来比 (*p)[10]方便多了。。。
	int i = 0;
	int j = 0;
	char * temp;

	// 创建副本。为了保存原始数据。
	char *p21[o];
	for(int i = 0; i < o; i++)
	{
		p21[i] = p1[i];
	}

	printf("\n打印效果如下:\n");

	for(i = 0; i < o-1; i++)
	{
		for(j = i + 1; j < o; j++)
		{
			if( strncmp(p21[j], p21[i], 1) < 0)
			{
				temp = p21[i];
				p21[i] = p21[j];
				p21[j] = temp;
			}
		}

		printf("%s\n", p21[i]);
	}

	// 根据外层for的表达式,在最后一次就退出循环,故而补一个输出语句。
	printf("%s\n", p21[i]);

	return;
}

void print3(char *p1[o])
{
	// 本函数构建思路:
	// 我打算创建一个 一维数组[o] , 然后for循环strlen出每个 p3[i]的长度,并保存到一位数组[i]中。
	// 然后再用嵌套for循环比较 一位数组[o]的各个值,再用嵌套循环的变量 i 和 j 来操作 p3[i] , p3[j]。
	// Tips: 根据自创的Debug集合,使用fgets()函数保存字符串的话,\n不处理掉,strlen会计算它。。请注意上下文。
	int i = 0;
	int j = 0;
	int temp1 = 0;
	char * temp;
	char length[o] = {};

	// 创建副本。为了保存原始数据。
	char *p31[o];
	for(int i = 0; i < o; i++)
	{
		p31[i] = p1[i];
	}

	// 保存10个字符串各自的长度。
	for(int i = 0; i < o; i++)
	{
		// 没问题。
		length[i] = strlen(p31[i]);
	}

	// 输出 操作3 结果。
	printf("\n打印结果如下:\n");
	for( i = 0; i < o-1; i++)
	{
		for( j = i + 1; j < o; j++)
		{
			if(length[i] > length[j])
			{	
				temp1 = length[i];
				length[i] = length[j];
				length[j] = temp1;

				temp = p31[i];
				p31[i] = p31[j];
				p31[j] = temp;
			}
			//printf("Line 227, %s, \n", p31[i]);
		}
		printf("%s\n", p31[i] );
	}

	// 根据外层for的表达式,在最后一次就退出循环,故而补一个输出语句。
	printf("%s\n", p31[i]);	

	return;
}

void print4(char *p1[o])
{
	// 思路:
	// 遍历这个数组,然后if判断空字符,再创建一个一位数组保存长度。
	// 再copy print3的代码,比较长度排序字符串后在输出。
	int length[o] = {};

	int i = 0;
	int j = 0;
	int leng = 0;		// 保存长度。

	int temp1 = 0;		
	char * temp;

	// 创建副本。
	char *p41[o];
	for(int i = 0; i < o; i++)
	{
		p41[i] = p1[i];
	}

	// 保存每个字符串第一个单词的长度。
	for(i = 0; i < o; i++)
	{
		for(leng = 0, j = 0; p41[i][j] != ' '; j++) 
		{
			leng++;
		}

		length[i] = leng;

		printf("\n测试:长度为 %d .\n", length[i] );
	}

	// 输出 操作4 结果。
	printf("\n打印结果如下:\n");
	for( i = 0; i < o-1; i++)
	{
		for( j = i + 1; j < o; j++)
		{
			if(length[i] > length[j])
			{	
				temp1 = length[i];
				length[i] = length[j];
				length[j] = temp1;

				temp = p41[i];
				p41[i] = p41[j];
				p41[j] = temp;
			}
		}
		printf("%s\n", p41[i] );
	}
	// 根据外层for的表达式,在最后一次就退出循环,故而补一个输出语句。
	printf("%s\n", p41[i]);	

	return;
}

void del_n(char *p1[o])
{
	// 本函数只为删除 fgets()函数储存的换行符。
	int i = 0;
	int j = 0;

	// 测试完毕~
	for(i = 0; i < o; i++)
	{
		for(j = 0; j < p; j++)
		{
			if(p1[i][j] == '\n')
			{
				p1[i][j] = '\0';
				break;
			}
		}
	}

	return;
}

猜你喜欢

转载自blog.csdn.net/Lth_1571138383/article/details/85843765
今日推荐