Table of contents

    문제개요

    이번 과제는 영문타자연습기로서 오타의 위치, 오타의 개수, 정확도 등등 을 출력해주며 텍스트 파일에 점수판을 구현하는 과제이다.

     

    문제 분석

    이번 과제에서 필요했던 기능들은, 파일 입출력, 구조체배열, 문자열 길이, 문자열 비교, 오타의 길이와 문장의 길이로 타자속도를 구하고, 이번 연습에서 가장 최고타자속도와 평균 타자속도를 화면에 출력해주어야 한다.

    또한 점수판은 구조체배열로 구성되어 있으며, 이때까지 저장되어 있던 점수판을 불러들여 최대 점수로 비교를 한뒤 순위별로 정렬(버블)을 해서 다시 score.txt 넣어주는 역할을 하는 기능들이 필요로 한다.

    또한 마지막으로 분할컴파일이 이번과제의 완성이 된다.

     

    참고

    처음에 1번은 게임시작
    2번은 점수판 보기

    게임시작후 이름을 작성하고 문장수를 선택한다.(최대10문장)

    각 문장이 끝날때마다, 그 문장에 대한 정보가 남고,
    한 게임(최대 10문장)이 끝나면 그 게임중 최고타자 속도가 높은
    점수가 점수판으로 갱신이 된다.
    점수판으로 갱신이 될 때에는
    현재 점수판을 불러들여서 정렬을 한뒤 20개로 맞추어서
    다시 정렬이 된다.

     

    main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define Rnd(a) rand()%a
    
    typedef struct
    {
    	char name[10]; // name
    	double aver; // average speed
    	double speed; // max speed
    }com;
    com rank[21]={{0,},};
    
    void my_str(char *, char *, double, double *, int);
    double my_speed(double *, int);
    double max_speed(double *,int);
    void bubble_sort(com *, int);
    void stringcopy(char *, char *);
    int stringlen(char *);
    
    void main()
    {
    	FILE *ifp; // test file
    	FILE *ofp;
    	char str1[10][55];
    	char *str2;
    	int i, menu;
    	int num; //몇번할껀지
    	int rannum; //random 숫자
    	int empty; //enter값을 받는곳..
    	double test[10];
    	double max;//이번연습에서의 최대 값
    	double res;
    
    	clock_t before;
    	double result;
    	srand(time(NULL)); //똑같은 숫자가 안나오게끔..
    
    	ifp = fopen("test.txt.","r");
    	if(ifp == NULL)
    		printf("Can't open test file.\n");
    
    	str2 = (char*)malloc(55*sizeof(char));
    	for(i = 0; i < 10; i++)
    	{
    		fgets(str1+i,sizeof(str1),ifp);
    	}
    	fclose(ifp); //연습문장 txt닫기
    
    	printf("> 선택하세요. (1:Start Test 2:Show Score-board) : ");
    	scanf("%d", &menu);
    
    	switch(menu)
    	{
    	case 1:
    		printf("이름을 입력하세요 : ");
    		scanf("%s", &rank[20].name);
    		printf("몇문장을 선택하겠습니까? (최대문장은 10문장) : ");
    		scanf("%d",&num);
    
    		for(i = 0; i < num; i++)
    		{
    			rannum = Rnd(10);
    			printf("\n");
    			puts(str1+rannum);
    			before  = clock();
    			scanf("%d",&empty); //이것은 선언 안하면 바로 넘어가기에 빈공간을 받을 변수를 하나더 선언했습니다..
    			gets(str2);
    			
    			result = (double)(clock() - before) / CLOCKS_PER_SEC; //시간구하는 공식
    			my_str(str1+rannum, str2, result, test, i);
    		}
    
    		res = my_speed(test, num); //평균속도 구하는 함수
    		printf("\n * Average typing speed is %5.2lf\n", res);
    		max = max_speed(test, num);
    		printf(" * Maximun typing speed is %5.2lf\n", max);
    		//
    
    		ofp=fopen("score.txt","r");
    		if(ofp==NULL)
    			printf("파일 개방 실패.\n");
    
    		for(i=0; i<20; i++)
    		{
    			fscanf(ofp,"%s %lf %lf", &rank[i].name, &rank[i].speed, &rank[i].aver); // name, max speed, average speed
    			if(rank[i].speed == 0)
    				break;
    		}
    		fclose(ofp);
    
    		ifp = fopen("score.txt","w");
    		stringcopy(rank[i].name, rank[20].name);
    		rank[i].aver = res;
    		rank[i].speed = max;
    
    		bubble_sort(rank, i+1);
    		printf("\n");
    		for(i = 0; i < 20; i++)
    		{
    			if(rank[i].speed == 0)
    				break;
    			fprintf(ifp, "%s %.2lf %.2lf\n", rank[i].name, rank[i].speed, rank[i].aver);
    			// printf("%s %.2lf %.2lf\n", rank[i].name, rank[i].speed, rank[i].aver); //잘들어오나 확인하는 작업..
    		}
    
    		break;
    
    	case 2:
    		ifp = fopen("score.txt","r");
    		if(ifp == NULL)
    			printf("파일 개방 실패.\n");
    	
    		printf("(  이 름  /    최대    /  평균타자  )\n");
    		for(i=0; i<20; i++)
    		{
    			fscanf(ifp,"%s %lf %lf", &rank[i].name, &rank[i].speed, &rank[i].aver);
    			if(rank[i].speed == 0)
    				break;
    			printf(" %5s %11.2lf %11.2lf\n", rank[i].name, rank[i].speed, rank[i].aver);
    		}
    
    		fclose(ifp);
    		break;
    
    	default:
    		printf("잘못된 값을 입력하셨습니다.\n");
    		break;
    	}
    }
    
    double my_speed(double *sp,int num)
    {
    	int i;
    	double sum = 0;
    	double aver;
    
    	for(i = 0; i < num; i++)
    		sum += sp[i];
    	
    	aver = sum / num;
    
    	return aver;
    }
    
    double max_speed(double *sp, int num)
    {
    	int i;
    	double max = 0;
    
    	for(i = 0; i < num; i++)
    		if(sp[i] > max)
    			max = sp[i];
    
    	return max;
    }
    
    
    void bubble_sort(com *sp, int n) 
    {
    	int i,j;
    	com temp;
    
    	for(i = 0; i < n-1; i++)
    		for(j = i+1; j < n; j++)
    			if(sp[i].speed < sp[j].speed)
    			{
    				temp = sp[i];
    				sp[i] = sp[j];
    				sp[j] = temp;
    			}
    }

    string.c

    #include <stdio.h>
    
    void my_str(char *str1, char *str2, double result, double *sp, int i) //오타의 위치, 개수, 타자의 정확도 함수
    {
    	double count = 0; //문장수
    	double discount = 0; //오타수
    	double good; //정확도
    
    	while(*str1 !='\0')
    	{
    		if(*str1 == *str2) //불러온 문장과 사용자에게 받은 문장이 같을시
    		{
    			count++;
    			printf(" ");
    		}
    		if(*str1 != *str2) //불러온 문장과 사용자에게 받은 문장이 다를시
    		{
    			if(*str1 == '\n'){
    				count++; //다르지만 불러온 문장이 줄바꿈인 경우에는 오타로 하지않는다.
    				printf(" ");
    			}
    			else // // 다른경우..
    			{
    				count++;
    				discount++;
    				//	printf("%.0lf번째가 오타가 났습니다.\n",count); //비교와 동시에 틀린경우 오타의 위치로 판단
    				printf("=");
    			}
    		}
    		str1++;
    		str2++;
    	}
    
    	good = (count-discount)/count*100; //정확도 계산 공식
    	printf("\n타자 정확도는 %.2lf입니다.\n", good);
    	printf("타자속도는 is %5.2lf입니다.\n", (count-discount) * 60 / result);
    
    	sp[i] = (count-discount) * 60 / result;//타자속도	
    }
    
    void stringcopy(char *dest, char *src)
    {
    	while( *src )
        {
            *dest++ = *src++;
        }
        *dest = 0 ;
    }
    
    int stringlen(char *src)
    {
        int count = 0; 
    
        while( *src++ )
            count++;
    
        return count;
    }