etc

small bits of code not worth their own repo
git clone git://git.benoneill.xyz/etc
Log | Files | Refs | README | LICENSE

typetest.c (1958B)


      1 /*
      2  * typetest.c: A simple typing speed test. Not very precise. Prints a
      3  * given file line by line and has user reproduce each one. It records
      4  * WPM, CPM, number of mistakes, and total time.
      5  * usage: typetest file
      6  * author: Ben O'Neill <ben@benoneill.xyz>
      7  * license: MIT
      8  */
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 #include <string.h>
     12 #include <time.h>
     13 
     14 typedef struct {
     15 	unsigned int mistakes, total_time, num_words;
     16 	float average_time;
     17 } result_t;
     18 
     19 result_t replication_test(FILE *);
     20 
     21 int main(int argc, char *argv[])
     22 {
     23 	FILE *fp;
     24 	result_t r;
     25 
     26 	if (argc == 2) {
     27 		fp = fopen(argv[1], "r");
     28 		if (fp == NULL) {
     29 			fprintf(stderr, "can't open file\n");
     30 			exit(EXIT_FAILURE);
     31 		}
     32 	} else {
     33 		fprintf(stderr, "usage: %s file\n", argv[0]);
     34 		exit(EXIT_FAILURE);
     35 	}
     36 
     37 	r = replication_test(fp);
     38 	fclose(fp);
     39 	printf("Number of mistakes: %d\nCharacters per minute: "
     40 			"%f\nWords per minute: %f\nTotal time: %d seconds\n",
     41 			r.mistakes, ((float) 60) / r.average_time,
     42 			60 / ((float) r.total_time / r.num_words), r.total_time);
     43 	return EXIT_SUCCESS;
     44 }
     45 
     46 /*
     47  * replicate the given file line by line, with no time limit.
     48  * content: string to replicate
     49  * returns: number of mistakes, average, and total times as result_t
     50  */
     51 result_t replication_test(FILE *fp)
     52 {
     53 	int mistakes = 0, c, i;
     54 	size_t len = 0;
     55 	size_t total_len = 0, words = 0;
     56 	ssize_t read;
     57 	char *line = NULL;
     58 	time_t start_time, end_time;
     59 	result_t r;
     60 
     61 	start_time = time(NULL);
     62 	while ((read = getline(&line, &len, fp)) != EOF) {
     63 		printf("%s> ", line);
     64 
     65 		total_len += read - 1;
     66 		for (i = 0; i < read; i++) {
     67 			if (line[i] == ' ' || line[i] == '\n')
     68 				words++;
     69 
     70 			c = getchar();
     71 			if (c == '\b') {
     72 				i--;
     73 			} else if (c != line[i]) {
     74 				mistakes++;
     75 			} else if (c == '\n') {
     76 				continue;
     77 			}
     78 		}
     79 	}
     80 	end_time = time(NULL);
     81 
     82 	r.mistakes = mistakes;
     83 	r.num_words = words;
     84 	r.total_time = end_time - start_time;
     85 	r.average_time = ((float) r.total_time) / total_len;
     86 	return r;
     87 }