明解C语言中级篇练习代码------第八章

马上开学了,第九章第十章看完了,但是练习题估计是来不及做了…
u1s1,这两章真的难…
希望有大佬能把9-1代码给我康康,感激不尽!!!

练习8-1

//List8-4 中随机排列了12个字符串供玩家练习。改写程序,这12个字符串不用全部出现,从中选择10个出题即可。并且,同一个字符串不能重复出现。

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define QNO		12
#define NEED    10           //宏定义变量NEED为需要完成的数量

#define swap(type, x, y)	do { type t = x; x = y; y = t; } while (0)

int main(void)
{
   
	char *str[QNO] = {
   "book",   "computer", "default",  "comfort",
					  "monday", "power",    "light",    "music",
					  "programming", "dog", "video",    "include"};
	int i, stage;
	int qno[QNO];
	clock_t	start, end;

	srand(time(NULL));

	for (i = 0; i < QNO; i++)
		qno[i] = i;

	for (i = QNO - 1; i > 0; i--) {
   
		int j = rand() % (i + 1);
		if (i != j)
			swap(int, qno[i], qno[j]);
	}

	printf("开始打字练习。\n");
	printf("按下空格键开始。\n");
	while (getch() != ' ')
		;

	start = clock();

	for (stage = 0; stage < NEED; stage++) {
                 //将条件stage<QNO改为NEED,此时顺序已打乱,但是只需要前十道题
		int len = strlen(str[qno[stage]]);
		for (i = 0; i < len; i++) {
   
			printf("%s \r", &str[qno[stage]][i]);

			fflush(stdout);
			while (getch() != str[qno[stage]][i])
				;
		}
	}

	end = clock();
	printf("\r用时%.1f秒。\n", (double)(end - start) / CLOCKS_PER_SEC);

	return 0;
}

练习8-2

//List8-7 中"C语言的单词训练"和"英语会话训练"使用了NO个字符串来出题。
//改写程序,使一次训练中出题时不会采用同一个字符串。

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define	NO			15			/* 训练次数 */
#define	KTYPE		16			/* 块数 */
#define	POS_LEN		10			/* 用于位置训练的字符数量 */

/*--- 练习菜单 ---*/
typedef enum {
    Term, KeyPos, KeyPosComp, Clang, Conversation, InValid } Menu;

/*--- 各个块的键 ---*/
char *kstr[] = {
   
	"12345",  "67890-^\\",		/* 第1层        */
	"!\"#$%", "&'()=~|",		/* 第1层[Shift] */
	"qwert",  "yuiop@[",		/* 第2层         */
	"QWERT",  "YUIOP`{",		/* 第2层[Shift]  */
	"asdfg",  "hjkl;:]",		/* 第3层         */
	"ASDFG",  "HJKL+*}",		/* 第3层[Shift]  */
	"zxcvb",  "nm,./\\",		/* 第4层         */
	"ZXCVB",  "NM<>?_",			/* 第4层[Shift]  */
};

/*--- C语言的关键字和库函数 ---*/
char *cstr[] = {
   
	"auto",		"break",	"case",		"char",		"const",	"continue",
	"default",	"do",		"double",	"else",		"enum",		"extern",
	"float",	"for",		"goto",		"if",		"int",		"long",
	"register",	"return",	"short",	"signed",	"sizeof",	"static",
	"struct",	"switch",	"typedef",	"union",	"unsigned",	"void",
	"volatile",	"while",
	"abort",	"abs",		"acos",		"asctime",	"asin",		"assert",
	"atan",		"atan2",	"atexit",	"atof",		"atoi",		"atol",
	"bsearch",	"calloc",	"ceil",		"clearerr",	"clock",	"cos",
	"cosh",		"ctime",	"difftime",	"div",		"exit",		"exp",
	"fabs",		"fclose",	"feof",		"ferror",	"fflush",	"fgetc",
	"fgetpos",	"fgets",	"floor",	"fmod",		"fopen",	"fprintf",
	"fputc",	"fputs",	"fread",	"free",		"freopen",	"frexp",
	"fscanf",	"fseek",	"fsetpos",	"ftell",	"fwrite",	"getc",
	"getchar",	"getenv",	"gets",		"gmtime",	"isalnum",	"isalpha",
	"iscntrl",	"isdigit",	"isgraph",	"islower",	"isprint",	"ispunct",
	"isspace",	"isupper",	"isxdigit",	"labs",		"ldexp",	"ldiv",
	"localeconv",			"localtime","log",		"log10",	"longjmp",
	"malloc",	"memchr",	"memcmp",	"memcpy",	"memmove",	"memset",
	"mktime",	"modf",		"perror",	"pow",		"printf",	"putc",
	"putchar",	"puts",		"qsort",	"raise",	"rand",		"realloc",
	"remove",	"rename",	"rewind",	"scanf",	"setbuf",	"setjmp",
	"setlocale","setvbuf",	"signal",	"sin",		"sinh",		"sprintf",
	"sqrt",		"srand",	"sscanf",	"strcat",	"strchr",	"strcmp",
	"strcoll",	"strcpy",	"strcspn",	"strerror",	"strftime",	"strlen",
	"strncat",	"strncmp",	"strncpy",	"strpbrk",	"strrchr",	"strspn",
	"strstr",	"strtod",	"strtok",	"strtol",	"strtoul",	"strxfrm",
	"system",	"tan",		"tanh",		"time",		"tmpfile",	"tmpnam",
	"tolower",	"toupper",	"ungetc",	"va_arg",	"va_end",	"va_start",
	"vfprintf", "vprintf",	"vsprintf"
};

/*--- 英语会话 ---*/
char *vstr[] = {
   
	"Hello!",							/* 你好。*/
	"How are you?",						/* 你好吗?*/
	"Fine thanks.",						/* 嗯,我很好。*/
	"I can't complain, thanks.",		/* 嗯,还行吧。*/
	"How do you do?",					/* 初次见面。*/
	"Good bye!",						/* 再见。*/
	"Good morning!",					/* 早上好。*/
	"Good afternoon!",					/* 下午好。*/
	"Good evening!",					/* 晚上好。*/
	"See you later!",					/* 再见(过会见)。*/
	"Go ahead, please.",				/* 您先请。*/
	"Thank you.",						/* 谢谢。*/
	"No, thank you.",					/* 不,谢谢。*/
	"May I have your name?",			/* 请问你叫什么名字?*/
	"I'm glad to meet you.",			/* 很高兴能见到你。*/
	"What time is it now?",				/* 请问现在是几点?*/
	"It's about seven.",				/* 大概7点。*/
	"I must go now.",					/* 我不得不走了。*/
	"How much?",						/* 多少钱?*/
	"Where is the restroom?",			/* 请问洗手间在哪里?*/
	"Excuse me.",						/* 抱歉(一人)。*/
	"Excuse us.",						/* 抱歉(两人以上)。*/
	"I'm sorry.",						/* 对不起。*/
	"I don't know.",					/* 我不知道。*/
	"I have no change with me.",		/* 我没带零钱。*/
	"I will be back.",					/* 我还会回来的。*/
	"Are you going out?",				/* 你要出门吗?*/
	"I hope I'm not disturbing you.",	/* 希望不会打搅到你。*/
	"I'll offer no excuse.",			/* 我没打算为自己辩解。*/
	"Shall we dance?",					/* 来跳舞吧。*/
	"Will you do me a favor?",			/* 你能帮我个忙吗?*/
	"It's very unseasonable.",			/* 这非常不合时节啊。*/
	"You are always welcome.",			/* 随时欢迎。*/
	"Hold still!",						/* 别动!*/
	"Follow me.",						/* 跟我来。*/
	"Just follow my lead.",				/* 跟着我做就好。*/
	"To be honest with you,",			/* 说真的……*/
};

/*--- 字符串str的打字练习(返回错误次数) ---*/
int go(const char *str)
{
   
	int i;
	int len = strlen(str);
	int mistake = 0;

	for (i = 0; i < len; i++) {
   
		printf("%s \r", &str[i]);
		fflush(stdout);
		while (getch() != str[i]) {
   
			mistake++;
		}
	}
	return mistake;
}

/*--- 单一位置训练 ---*/
void pos_training(void)
{
   
	int i;
	int stage;
	int temp, line;
	int len;
	int qno, pno;
	int tno, mno;
	clock_t	start, end;

	printf("\n进行单一位置训练。\n");
	printf("请选择要练习的块。\n");
	printf("第1层 (1) 左 %-8s    (2) 右 %-8s\n", kstr[ 0], kstr[ 1]);
	printf("第2层 (3) 左 %-8s    (4) 右 %-8s\n", kstr[ 4], kstr[ 5]);
	printf("第3层 (5) 左 %-8s    (6) 右 %-8s\n", kstr[ 8], kstr[ 9]);
	printf("第4层 (7) 左 %-8s    (8) 右 %-8s\n", kstr[12], kstr[13]);

	do {
   
		printf("编号(停止练习为99):");
		scanf("%d", &temp);
		if (temp == 99) return;
	} while (temp < 1 || temp > 8);
	line = 4 * ((temp - 1) / 2) + (temp - 1) % 2;

	printf("练习%s次%d题目。\n", NO, kstr[line]);        //书本刊印错误

	printf("按下空格键开始。\n");
	while (getch() != ' ')
		;

	tno = mno = 0;
	len = strlen(kstr[line]);

	start = clock();

	for (stage = 0; stage < NO; stage++) {
   
		char str[POS_LEN + 1];

		for (i = 0; i < POS_LEN; i++)
			str[i] = kstr[line][rand() % len];
		str[i] = '\0';

		mno += go(str);
		tno += strlen(str);
	}

	end = clock();

	printf("题目:%d字符/错误:%d次\n", tno, mno);
	printf("用时%.1f秒。\n", (double)(end - start) / CLOCKS_PER_SEC);
}

/*--- 混合位置训练 ---*/
void pos_training2(void)
{
   
	int i;
	int stage;
	int temp, line;
	int sno;
	int select[KTYPE];
	int len[KTYPE];
	int tno, mno;
	clock_t	start, end;
	char *format = "第%d层 (%2d) 左 %-8s (%2d) 右 %-8s "
					      "(%2d)[左] %-8s (%2d)[右] %-8s\n";

	printf("\n进行混合位置训练。\n");
	printf("请选择要练习的块(可以多选)。\n");

	for (i = 0; i < 4; i++) {
   
		int k = i * 4;
		printf(format, i+1, k + 1, kstr[k],		k + 2, kstr[k + 1],
							k + 3, kstr[k + 2], k + 4, kstr[k + 3]);
	}

	sno = 0;
	while (1) {
   
		printf("编号(结束选择为50/停止练习为99):");

		do {
   
			scanf("%d", &temp);
			if (temp == 99) return;
		} while ((temp < 1 || temp > KTYPE) && temp != 50);

		if (temp == 50)
			break;
		for (i = 0; i < sno; i++)
			if (temp == select[i]) {
   
				printf("\a这一层已经被选过了。\n");
				break;
			}
		if (i == sno)
			select[sno++] = temp;
	}

	if (sno == 0)
		return;

	printf("把下列块的题目练习%d次。\n", NO);

	for (i = 0; i < sno; i++)
		printf("%s ", kstr[select[i] - 1]);

	printf("\n按下空格键开始。\n");
	while (getch() != ' ')
		;

	tno = mno = 0;
	for (i = 0; i < sno; i++)
		len[i] = strlen(kstr[select[i] - 1]);

	start = clock();

	for (stage = 0; stage < NO; stage++) {
   
		char str[POS_LEN + 1];

		for (i = 0; i < POS_LEN; i++) {
   
			int q = rand() % sno;
			str[i] = kstr[select[q] - 1][rand() % len[q]];
		}
		str[i] = '\0';

		mno += go(str);
		tno += strlen(str);
	}

	end = clock();

	printf("题目:%d字符/错误:%d次\n", tno, mno);
	printf("用时%.1f秒。\n", (double)(end - start) / CLOCKS_PER_SEC);
}

/*--- C语言/英语会话训练 ---*/
void word_training(const char *mes, const char *str[], int n)
{
   
	int stage;
	int qno[NO];                                //因为要检查所有出现的字符串之后重复,所以用数组来储存随机出现的题号
	int tno, mno;
	int i;
	clock_t	start, end;

	printf("\n练习%d个%s。\n", NO, mes);        //书本刊印错误

	printf("按下空格键开始。\n");
	while (getch() != ' ')
		;

	tno = mno = 0;

	start = clock();

	for (stage = 0; stage < NO; stage++) {
   
		do {
   
			qno[stage] = rand() % n;

			for (i=stage-1; i>=0; i--) {
           //将qno[stage]与数组中stage前的每一个元素比较,如果有相同的题号出现,i肯定大于-1,此时跳出循环重新随即赋值。
                if (qno[stage] == qno[i])
                    break;
            }
		} while (i != -1);                      //若没有重复,此时内for循环走到最后,i=-1,将此作为while循环条件。

		mno += go(str[qno[stage]]);
		tno += strlen(str[qno[stage]]);
	}

	end = clock();

	printf("题目:%d字符/错误:%d次\n", tno, mno);
	printf("用时%.1f秒。\n", (double)(end - start) / CLOCKS_PER_SEC);
}

/*--- 选择菜单 ---*/
Menu SelectMenu(void)
{
   
	int ch;

	do {
   
		printf("\n请选择练习。\n");
		printf("(1) 单一位置       (2) 混合位置\n");
		printf("(3) C语言的单词    (4) 英语会话      (0) 结束 :");
		scanf("%d", &ch);
	} while (ch < Term || ch >= InValid);

	return (Menu)ch;
}

int main(void)
{
   
	Menu menu;
	int cn = sizeof(cstr) / sizeof(cstr[0]);
	int vn = sizeof(vstr) / sizeof(vstr[0]);

	srand(time(NULL));

	do {
   
		switch (menu = SelectMenu()) {
   

		 case KeyPos :						/* 单一位置训练 */
		 			pos_training();
		 			break;

		 case KeyPosComp :					/* 混合位置训练 */
		 			pos_training2();
		 			break;

		 case Clang :						/* C语言的单词 */
		 			word_training("C语言的单词", cstr, cn);
		 			break;

		 case Conversation :				/* 英语会话 */
		 			word_training("英语会话的文档", vstr, vn);
		 			break;
		}
	} while (menu != Term);

	return 0;
}

练习8-3

//List8-7 的“英语对话训练”中,显示要输入的文档的中文翻译后,玩家不仅能练习打字,还能练习英语会话。因此请在上一题编好的程序中追加一个让玩家输入英文的模式。

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define	NO			15			/* 训练次数 */
#define	KTYPE		16			/* 块数 */
#define	POS_LEN		10			/* 用于位置训练的字符数量 */

/*--- 练习菜单 ---*/
typedef enum {
    Term, KeyPos, KeyPosComp, Clang, Conversation, InValid } Menu;

/*--- 各个块的键 ---*/
char *kstr[] = {
   
	"12345",  "67890-^\\",		/* 第1层        */
	"!\"#$%", "&'()=~|",		/* 第1层[Shift] */
	"qwert",  "yuiop@[",		/* 第2层         */
	"QWERT",  "YUIOP`{",		/* 第2层[Shift]  */
	"asdfg",  "hjkl;:]",		/* 第3层         */
	"ASDFG",  "HJKL+*}",		/* 第3层[Shift]  */
	"zxcvb",  "nm,./\\",		/* 第4层         */
	"ZXCVB",  "NM<>?_",			/* 第4层[Shift]  */
};

/*--- C语言的关键字和库函数 ---*/
char *cstr[] = {
   
	"auto",		"break",	"case",		"char",		"const",	"continue",
	"default",	"do",		"double",	"else",		"enum",		"extern",
	"float",	"for",		"goto",		"if",		"int",		"long",
	"register",	"return",	"short",	"signed",	"sizeof",	"static",
	"struct",	"switch",	"typedef",	"union",	"unsigned",	"void",
	"volatile",	"while",
	"abort",	"abs",		"acos",		"asctime",	"asin",		"assert",
	"atan",		"atan2",	"atexit",	"atof",		"atoi",		"atol",
	"bsearch",	"calloc",	"ceil",		"clearerr",	"clock",	"cos",
	"cosh",		&#
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值