因此,我拥有将英语翻译成 Pig Latin 的程序的全部功能。我有大约 80% 的反向翻译功能。
我有两个问题:
首先,当从 Pig Latin 翻译回英语时,它会在第一个超过 7 个字符的输入单词的末尾添加一些乱码。它不会对短语中的任何其他单词再次执行此操作,并且仅在从 Pig Latin 转换为英语时才会执行此操作。
第二个是更多的逻辑问题。我想不出如何检查英语单词以 T 开头并以元音结尾的情况。例如:time
翻译成 PL 将是imetay
. 然而,虽然不是一个实际的单词,eim
但也可以imetay
在 PL 中翻译为 不检查原始英语短语,如何判断imetay
应该是time
还是eim
?
那里留下了一些调试行来显示反向翻译中的乱码会发生什么。
//Matthew Gerton
//Project 3 - Pig latin translator
//11/26/14
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
//structures for Node and Queue
typedef struct node
{
char word[20];
struct node * link;
}node;
typedef struct queue
{
node * front;
node * rear;
} queue;
queue *input = NULL, *trans = NULL;
//method prototypes
void break_and_translate(char * phrase, int z);
queue * buildPhrase(queue * abcd, char data[20]);
node * translate(node * data);
node * translateBack(node * nextWord);
void displayP(node * abcd);
int isWordSep(char a);
int isVowel(char a);
//main function drives switch statement method for entering, translating, displaying and clearing the queues
int main()
{
int ch, ch2;
char dummy;
char * phrase;
do
{
printf("\n\n1.\tInput phrase\n2.\tTranslate phrase\n3.\tDisplay phrase\n4.\tDisplay Translation\n5.\tClear current phrase and translation\n6.\tExit\n");
printf("\nEnter your choice: ");
scanf("%d", &ch);
scanf("%c", &dummy);
switch(ch)
{
//mallocs memory for the input phrase and scans the input phrase. breaks the phrase into a queue and translates it.
//then frees the memory for the phrase.
case 1:
phrase = (char *)malloc(1024 * sizeof(char));
printf("Input the phrase to be translated.\n");
gets(phrase);
if(phrase==NULL)
printf("Sorry, cant read the phrase. Try again.");
else
printf("Phrase recieved!!!!\n");
break;
//calls the method to translate the input stored in phrase
case 2:
printf("Are you tanslating from:\n1. English into pig latin\n2. Pig latin to english\n");
scanf("%d", &ch2);
scanf("%c", &dummy);
break_and_translate(phrase, ch2);
if(input ==NULL || trans ==NULL)
{
printf("Translation uncessful. Rerun the program and try again!\n");
exit(0);
}
else
printf("Translation sucessfull!!!!\n");
break;
//Display the input phrase.
case 3:
if(phrase==NULL)
printf("No phrase entered. Please enter a phrase to translate\n");
else
printf("%s\n", phrase);
break;
//Display the translated phrase
case 4:
if(input==NULL)
printf("Translation has not been prepared yet.\nPlease either enter a phrase to translate, or translate the current phrase.\n");
else
displayP(trans->front);
break;
//sets the queues back to null and frees the memory allocated to the phrase.
case 5:
if(input ==NULL && trans ==NULL)
{
if(phrase == NULL)
printf("\nNothing to reset yet! Enter and translate a phrase!\n");
else
printf("No tanslation yet, clearing the input phrase.\n");
}
input = trans = NULL;
free(phrase);
phrase = NULL;
printf("Reset sucessfull!!!!\n");
break;
//exit
case 6:
printf("Goodbye!!!!\n");
exit(0);
default:
printf("\n\nInvalid choice. Please try again...\n");
}
} while(1);
return (ch);
}
//initializes memory for a new queue
queue * new_queue()
{
queue *s = (queue *)malloc(sizeof(queue));
s->front = NULL;
s->rear = NULL;
return s;
}
//takes a queue input and string and adds a node the rear of the queue containing that string
//returns a pointer to the queue;
queue * buildPhrase(queue * abcd, char data[20])
{
if(abcd==NULL)
{
abcd=new_queue();
}
if(abcd->rear == NULL)
{
abcd ->rear = (node *)malloc(sizeof(node));
strcpy(abcd->rear->word, data);
abcd -> rear->link = NULL;
abcd ->front = abcd ->rear;
}
else
{
abcd ->rear->link = (node *)malloc(sizeof(node));
abcd ->rear = abcd ->rear->link;
strcpy(abcd->rear->word, data);
abcd ->rear->link = NULL;
}
return abcd;
}
//Takes a node as an input. Allocates memory for a new node for the latin word
//Takes the first letter from the input nodes word, moves shifts everyting left one char into the latin word
//Checks to see if the first letter was a capital letter. If so, adds the lowecase char to the end and capitalizes the first
//Then checks to see if the first char was a vowel or capital vowel. if so, adds t to the end of the latin word. then adds 'a' and 'y' regardless
//then returns the node for the latin translation.
node * translate(node * nextWord)
{
char a; int b, c=0;
a=nextWord ->word[0];
node * latin = (node *)malloc(sizeof(node));
if(isWordSep(a)==0)
{
for(b=1; b<strlen(nextWord->word); b++)
{
latin->word[b-1] = nextWord->word[b];
c=b;
}
if((a>=65) && (a<= 91))
{
latin->word[0] = (latin->word[0]-32);
latin->word[c++] = (a+32);
}
else
latin->word[c++] = a;
if(isVowel(a)==1)
{
latin->word[c++]='t';
}
latin->word[c++]='a';
latin->word[c++]='y';
}
return latin;
}
//takes the input phrase as a parameter. goes through the phrase until a "whitespace char" is found
//when one is found allocates memory for 2 node pointers, coppies the word up until that point to one pointer
//passes that pointer to the trsanslate method, translates it an returns it as the second pointer. It then adds the punctuation
//to the end of each word then passes each node to the build queue method. Then frees the memory for the nodes and resets the word array
void break_and_translate(char * phrase, int z)
{
int space =0, b=0, c=0;
char end, word[20];
memset(word, '\0', strlen(word));
end = phrase[0];
while(end != '\0')
{
end = phrase[b];
printf("END: %c\n", end);
if(isWordSep(end)==0)
{
word[space]= end;
space++;
printf("WORD: %s\nstrlen WORD: %d\n", word, strlen(word));
}
else
{
node * temp = (node *)malloc(sizeof(node));
node * temp2 = (node *)malloc(sizeof(node));
strcpy(temp->word, word);
if(z==1)
temp2 = translate(temp);
else
temp2 = translateBack(temp);
c = strlen(temp2->word);
temp2->word[c]= word[space] = end;
strcpy(temp->word, word);
// printf("\n%s temp word\n%s temp2 word\n", temp->word, temp2->word);
input = buildPhrase(input, temp->word);
trans = buildPhrase(trans, temp2->word);
memset(word, '\0', strlen(word));
free(temp);
free(temp2);
space=0;
printf("WORD: %s\n", word);
}
b++;
}
}
//takes a pointer to the head of a queue and prints each word of each node.
void displayP(node * abcd)
{
int a = 0;
node *ptr = (node *) malloc(sizeof(node));
ptr = abcd;
printf("\n");
while(ptr != NULL)
{
printf("%s",ptr->word);
a++;
ptr = ptr->link;
}
free(ptr);
}
node * translateBack(node * nextWord)
{
char a, x, y, z; int b, c=0, d;
node * latinBack = (node *)malloc(sizeof(node));
strcpy(latinBack->word, nextWord->word);
z = latinBack->word[0];
d = strlen(latinBack ->word);
if(isWordSep(z)==0)
{
a=latinBack ->word[d-3];
if((isVowel(a)==0)&&(a!='t'))
{
latinBack->word[d-2] = latinBack->word[d];
}
else if(a=='t')
{
x = nextWord ->word[d-4];
y = nextWord ->word[d-5];
if((isVowel(x)==1)&&(isVowel(y)==1))
{
latinBack->word[d-3] = latinBack->word[d];
latinBack->word[d-2] = '\0';
a=x;
}
else
latinBack->word[d-2] = latinBack->word[d];
}
latinBack->word[d-1] = '\0';
latinBack->word[d] = '\0';
for(b=strlen(latinBack->word); b>0; b--)
latinBack->word[b] = latinBack->word[b-1];
latinBack->word[0] = a;
latinBack->word[strlen(latinBack->word)-1]='\0';
z=latinBack->word[1];
if((z>=65) && (z<= 91))
{
latinBack->word[0]= (latinBack->word[0]-32);
latinBack->word[1]= (latinBack->word[1]+32);
}
}
return latinBack;
}
int isWordSep(char a)
{
if ((a==' ')||(a=='.')||(a==',')||(a=='!')||(a==';')||(a=='?')||(a=='\n')||(a=='\0'))
return 1;
else
return 0;
}
int isVowel(char a)
{
if((a == 'a')||(a=='e')||(a=='i')||(a=='o')||(a=='u')||(a == 'A')||(a=='E')||(a=='I')||(a=='O')||(a=='U'))
return 1;
else
return 0;
}