欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言实现简易金山打字通

程序员文章站 2022-07-16 18:54:40
...

本小项目最终的实现如下:

输入相应的字符,然后在最下面能够统计错误的个数,输入字符总个数,输入个数以及错误率。

C语言实现简易金山打字通

C语言实现简易金山打字通

那如何来实现这个小项目呢?规划如下,我们需要大致实现以下三个模块:

(1)输入模块

(2)显示模块

(3)统计模块

实现过程:

使用getch()函数可以获取键盘输入的字符,显示可以使用Window自带的API来实现,统计就很简单了,就是计算输入字符的个数等等。。。接下来就是简单的软件逻辑的实现。

源码如下:

#include <stdio.h>
#include <string.h>
#include <Windows.h>
#include <unistd.h>
#include <conio.h>
#define NR(x)  sizeof(x)/sizeof(x[0])
	
//清屏
#define ClearScreen() \
	    system("cls");
	
#define  TITLE  "金山打字通----杨源鑫20180608"    

enum
{
	LEFT = 1 ,
	RIGHT ,
	BACKSPACE ,
	ESC ,
	Char,
};

enum KEYBOARD
{
	ESC_KEY = 27,
	BACKSPACE_KEY = 8 ,
	LEFT_KEY = 75 ,
	RIGHT_KEY = 77
};

int iindex = 0 ;
int max = 0 ; 
static int count = 0 ;
char buffer[1024] = {0} ;
int Get_User_input(HANDLE hOut,char *ch) ;
void Show_string(HANDLE hOut,const char *text) ;
//窗口初始化
void HANDLE_init(HANDLE hOut);
//定义设置光标结构体变量
CONSOLE_CURSOR_INFO cci; 
//定义默认的坐标位置  	
COORD pos = {0,0};

int main(void)
{
	char *text = "WelCome to School ... Good Good Work ,Day Day Up !" ;
	char ch ;
	int ret ;
	HANDLE hOut;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	HANDLE_init(hOut);
	printf("\n%s\n",text);
	Show_string(hOut,text);
	while(1)
	{
		if(max >= strlen(text))
			break ;
		ret = Get_User_input(hOut,&ch) ;
		if(ret == ESC)
			break ;
		Show_string(hOut,text);
	}
	//关闭窗口句柄
	CloseHandle(hOut);
	return 0 ;
}


//窗口初始化
void HANDLE_init(HANDLE hOut)
{
	SetConsoleTitleA(TITLE);
	//获取当前的句柄---设置为标准输出句柄 
    //获取光标信息
    GetConsoleCursorInfo(hOut, &cci); 
	//设置光标大小   
	pos.X = 0 ; 
	pos.Y = 2 ;
    cci.dwSize = 1; 
	//设置光标不可见 FALSE   
    cci.bVisible =  0; 
    //设置(应用)光标信息
    SetConsoleCursorInfo(hOut, &cci);
}

static int __Get_User_input(HANDLE hOut,char *ch) 
{
	char tmp ;
	int type = Char ;
	
	//关闭回显 
	pos.X = 0 ; 
	pos.Y = 2 ;
	GetConsoleCursorInfo(hOut, &cci); 
	cci.dwSize = 100; 
    cci.bVisible =  0;
	SetConsoleCursorInfo(hOut, &cci);  
	tmp = getch() ;
	switch(tmp)
	{
		case ESC_KEY : type = ESC ; break ; 
		case BACKSPACE_KEY : type = BACKSPACE ; break ;
		case LEFT_KEY : type = LEFT ; break ; 
		case RIGHT_KEY : type = RIGHT; break ;
	}
	*ch = tmp ;
	
	//打开回显 
	pos.X = 0 ; 
	pos.Y = 2 ;
	GetConsoleCursorInfo(hOut, &cci); 
	cci.dwSize = 100; 
    cci.bVisible =  1;
	SetConsoleCursorInfo(hOut, &cci); 
	return type ;
}

//获取用于输入 
int Get_User_input(HANDLE hOut,char *ch)
{
	int type ; 
	type = __Get_User_input(hOut,ch);
	switch(type)
	{
		case Char : 
					if(buffer[iindex] == '\0' ) 
						buffer[iindex] = *ch ;
					else
					{
						memmove(buffer+iindex+1 , buffer+iindex , max-iindex) ;
						buffer[iindex] = *ch ;
					}
					iindex ++ ; max ++ ; break ;
		//case LEFT  : if(iindex > 0) iindex -- ;  break ;
		//case RIGHT : if(iindex < max) iindex ++ ; break ;
		case BACKSPACE : 
					if(iindex > 0){
						memmove(buffer+iindex-1 , buffer+iindex , max-iindex) ; 
						iindex -- ; 
						max -- ;
					}
					if(iindex == 0)
					{
						count = 0 ; 
					}
					break ;
		case ESC : return ESC ;
		
	}
	return 0 ;
}

//显示和统计 
void Show_string(HANDLE hOut,const char *text)
{
	system("cls") ;
	printf("\n%s\n",text) ;
	int i ; 
	int errno_Num = 0 ; 
	for(i = 0 ; i < max ; i++)
	{
		if(buffer[i] == text[i])
		{
			SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8);
			printf("%c",buffer[i]);
		}
		else 
		{
			SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8);
			printf("%c",buffer[i]);
			errno_Num++ ;
		}
	}

	
	pos.X = 0 ; 
	pos.Y = 2 ;
	cci.dwSize = 100; 
	cci.bVisible = 1 ;
	SetConsoleCursorPosition(hOut,pos);
	SetConsoleCursorInfo(hOut, &cci); 


	SetConsoleTextAttribute(hOut,FOREGROUND_GREEN | 0x8);
	pos.X = 0;
	pos.Y = 15 ;
	SetConsoleCursorPosition(hOut,pos);
	printf("错误的个数:%d", errno_Num) ;
	
	pos.X = 0;
	pos.Y = 16 ;
	SetConsoleCursorPosition(hOut,pos);
	printf("总个数:%d", (int)strlen(text)) ;
	pos.X = 0;
	pos.Y = 17 ;
	SetConsoleCursorPosition(hOut,pos);
	printf("输入个数:%d", max) ;
	pos.X = 0;
	pos.Y = 18 ;
	SetConsoleCursorPosition(hOut,pos);
	if(count == 0)
		printf("错误率:0%%") ;
	else
		printf("错误率:%.2f%%",((float)errno_Num)/((float)max)*100) ;
	pos.X = iindex + 1 ; 
	pos.Y = 2 ;
	cci.dwSize = 100; 
	cci.bVisible = 1 ;
	count = 1 ;
	SetConsoleCursorPosition(hOut,pos);
	SetConsoleCursorInfo(hOut, &cci); 
	fflush(stdout);
}