langtest.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include "list.h"
int GetInput(int argc, char *argv[]);
int Rndm(int lower, int higher);
int Getline(char *buffer, int maxlen, FILE *fp);
char langs[2][MAX_LINE];
int main(int argc, char *argv[]) {
int nPhrases, q, lang1, lang2;
char *phrase[2], buffer[MAX_LINE] = {0};
srand( (unsigned) time(NULL) );
nPhrases = GetInput(argc, argv);
while ( buffer[0] != 'q' && buffer[0] != 'Q' ) {
q = Rndm(0, nPhrases-1);
lang1 = Rndm(0, 1);
lang2 = lang1 ? 0 : 1;
GetItem(q, &phrase[0], &phrase[1]);
printf("The %s is %s\n", langs[lang1], phrase[lang1]);
printf("Enter the %s: ", langs[lang2]);
fgets(buffer, MAX_LINE-1, stdin);
printf("The %s is %s\n\n", langs[lang2], phrase[lang2]);
}
FreeList();
return EXIT_SUCCESS;
}
int GetInput(int argc, char *argv[]) {
int i, a = 1, length = 0;
FILE *fp;
char buffer1[MAX_LINE], buffer2[MAX_LINE];
while ( argv[a] ) {
if ( ! (fp = fopen(argv[a], "r")) ) {
printf("LANGTEST: Error opening %s for reading...", argv[a]);
printf("skipping\n");
continue;
}
for ( i = 0; i < 2; i++ ) {
if (Getline(buffer1, sizeof(langs[0])/sizeof(langs[0][0])-1, fp)) {
Trim(buffer1);
strcpy(langs[i], buffer1);
}
else {
printf("LANGTEST: Error determining languages.\n");
exit(EXIT_FAILURE);
}
}
while ( Getline(buffer1, MAX_LINE-1, fp) ) {
if ( Getline(buffer2, MAX_LINE-1, fp) ) {
Trim(buffer1);
Trim(buffer2);
if ( AppendItem(buffer1, buffer2) ) {
printf("LANGTEST: Failed to allocate item.\n");
exit(EXIT_FAILURE);
}
++length;
}
else
break;
}
++a;
fclose(fp);
}
return length;
}
int Rndm(int lower, int higher) {
int range = higher - lower + 1;
return lower + (int)((double) rand() / ((double)RAND_MAX + 1) * range);
}
int Getline(char *buffer, int maxlen, FILE *fp) {
char *temp;
do {
if ( !fgets(buffer, maxlen, fp) )
return 0;
temp = buffer;
while ( *temp && isspace(*temp) )
++temp;
} while ( *temp == 0 || *temp == '#' );
return 1;
}
list.h
#ifndef PG_LIST_H
#define PG_LIST_H
#define MAX_LINE (100)
int AppendItem(char *foreign, char *english);
int FreeList();
int GetItem(int index, char **phrase1, char **phrase2);
int Trim(char *buffer);
#endif
list.c
#include <stdlib.h>
#include <ctype.h>
#include "list.h"
typedef struct node {
char *phrase[2];
struct node *next;
} node;
node *startnode = NULL, *endnode = NULL;
int AppendItem(char *phrase1, char *phrase2) {
node *tempnode;
if ( !endnode ) {
if ( ! (startnode = malloc(sizeof(node))) )
return 1;
endnode = startnode;
startnode->next = NULL;
}
else {
if ( ! (tempnode = malloc(sizeof(node))) )
return 1;
endnode->next = tempnode;
endnode = tempnode;
}
endnode->next = NULL;
if ( ! (endnode->phrase[0] = malloc(strlen(phrase1)+1)) )
return 1;
strcpy(endnode->phrase[0], phrase1);
if ( ! (endnode->phrase[1] = malloc(strlen(phrase2)+1)) )
return 1;
strcpy(endnode->phrase[1], phrase2);
return 0;
}
int GetItem(int index, char **phrase1, char **phrase2) {
int n = 0;
node *tempnode = startnode;
while ( index > n++ )
tempnode = tempnode->next;
*phrase1 = tempnode->phrase[0];
*phrase2 = tempnode->phrase[1];
return 0;
}
int FreeList() {
node *tempnode = startnode;
while ( tempnode ) {
free(tempnode->phrase[0]);
free(tempnode->phrase[1]);
startnode = tempnode->next;
free(tempnode);
tempnode = startnode;
}
return 0;
}
int Trim(char *buffer) {
int n = strlen(buffer) - 1;
while ( !isalnum(buffer[n]) )
buffer[n--] = '\0';
return 0;
}
testdata.dat
# testdata.dat
#
# Sample LANGTEST data file
#
# These lines are comments
# The first two uncommented lines signify the
# two languages we will be translating. They
# should be in the same order as the pairs of
# phrases which follow
Japanese
English
# Now that we have specified our languages,
# we can list the pairs of phrases in the
# order specified above. Blank lines are
# ignored by LANGTEST, so we can use them or
# omit them as we please.
O-hayo gozaimasu
Good morning
Konnichi wa
Hello
Konban wa
Good evening
O-yasumi nasai
Good night
Hajimemashite
Pleased to meet you
Sayonara
Goodbye
O-namae wa nan to osshaimasu ka
What is your name?
Tanaka to moshimasu
My name is Tanaka
Sumimasen
Excuse me
Please send all comments, suggestions, bug reports etc to mail@paulgriffiths.net