马上开学了,第九章第十章看完了,但是练习题估计是来不及做了…
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", &#