//用链表实现背单词系统
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
/*
背单词系统
实现的功能
1.支持单词的录入
2.支持英查汉
3.支持汉查英
4.支持背单词
5.支持单词的持久化保存
6.有生词本功能
7.统计背单词的相关信息
8.可以读全部保存的单词
*/
typedef struct node{
char eng[50];
char chi[20];
struct node* next;
}Node;
//代码中用了两个链表两个文件,一个用于存放单词,一个用于生词本
int createlink();//将字典文件中的数据导入到链表
Node* list_init(); //初始化链表
void print_list(Node* head);//打印所有单词
int search_chi(Node* head);//英查汉
int print_list1(Node* head);//返回单词个数
void tail_insert(Node* head);//尾插
int search_eng(Node* head);//汉查英
Node* rem_word(Node*head,int count,Node* un_head);//背单词
//char* fin_word(Node*head,int count);
Node* unknow_list_init();//初始化生词的链表
int createlink1(Node* un_head);//将生词文件中的数据打印到链表
void tail_insert_un(Node* unhead,Node* p);//尾插生词
int print_list_un(Node* un_head);//打印生词表
//初始化链表
Node* list_init()
{
Node* head = (Node*)malloc(sizeof(Node));//申请一个头节点空间
//判断是否申请成功
assert(head);
//初始化
strcpy(head->eng,"0");
strcpy(head->chi,"0");
head->next=NULL;
return head;//返回头节点
}
//尾插法向链表中放入单词
void tail_insert(Node* head)
{
createlink();
//开辟一个新的节点,向尾部链接
Node* new_node = (Node*)malloc(sizeof(Node));
assert(new_node);
//初始化新节点
char new_word[40]="0";
char new_chi[20]="0";
printf("请输入录入单词\n");
scanf("%s",new_word);
getchar();
printf("请输入录入单词的意思\n");
scanf("%s",new_chi);
getchar();
strcpy(new_node->eng,new_word);
strcpy(new_node->chi,new_chi);
new_node->next = NULL;
assert(head);//判断头指针是否为空
//定义一个临时变量p,来代替head移动
Node* p = head;
//找到尾节点
while(p->next!=NULL)
{
p=p->next;
}
//将添加到节点的元素追加到fp文件中
FILE* fp=fopen("/mnt/hgfs/share/Sep/dictionary.txt","a+");
fprintf(fp,"%s %s",new_node->eng,new_node->chi);
fprintf(fp,"\n");
fclose(fp);
//尾插,连接节点
p->next = new_node;
}
//汉查英
int search_eng(Node* head)
{
createlink();//将文件中的内容读到链表中
assert(head);
Node* p = head;
printf("请输入汉语:\n");
char chinese[50]="0";
scanf("%s",chinese);
while(p->next!=NULL)
{
p=p->next;
if(strcmp(p->chi,chinese)==0)
{
printf("%s\n",p->eng);
}
}
// printf("还没录入此单词!\n");
return -1;
}
//英查汉
int search_chi(Node* head)
{
createlink();//将文件中的内容读到链表中
assert(head);
Node* p = head;
printf("请输入英文:\n");
char english[50]="0";
scanf("%s",english);
while(p->next!=NULL)
{
p=p->next;
if(strcmp(p->eng,english)==0)
{
printf("%s\n",p->chi);
}
}
// printf("还没录入此单词!\n");
return -1;
}
//遍历并打印整个链表
void print_list(Node* head)
{
createlink();
Node* p=head;
assert(p);
while(p->next!=NULL)
{
p=p->next;
// count++;
printf("%s %s\n",p->eng,p->chi);
}
//printf("%d\n",count);
//return count;
}
//计算单词个数
int print_list1(Node* head)
{
createlink();
Node* p=head;
assert(p);
int count=0;
while(p->next!=NULL)
{
p=p->next;
count++;
//printf("%s %s\n",p->eng,p->chi);
}
//printf("%d\n",count);
return count;
}
//从文件中读取数据存入链表
int createlink(Node*head)
{
//创建新的链表,将读到的数据存入链表中
//Node *head =(Node*)malloc(sizeof(Node));
Node* h = head;
char new_eng[50];
char new_chi[40];
Node *p=h;
Node *q=h;
FILE * r= fopen("/mnt/hgfs/share/Sep/dictionary.txt","r");
if(r==NULL)
{
printf("打开文件失败!");
return -1;
}
while(fscanf(r,"%s %s",new_eng,new_chi)!=EOF)
{
q= (Node*)malloc(sizeof(Node));
strcpy(q->eng,new_eng);
strcpy(q->chi,new_chi);
p->next=q;
p=q;
}
p->next=NULL;
fclose(r);
// return h;
}
//背单词功能
Node* rem_word(Node*head,int count,Node* un_head)
{
int error = 0;//计数
int i = 0;
for(i=0;i<10;i++)
{
Node* p = head;
int num=0;//记录随机拿出节点的索引,利用索引找到出单词
int s=rand()%count+1;//rand产生一个1~count间的
//随机生成一个单词
while(p->next!=NULL)
{
p=p->next;
num++;
if(num==s)
{
printf("%s",p->eng);//生成p->eng
break;
}
}
char ch[20]={0};
scanf("%s",ch);
if(strcmp(ch,p->chi)==0) //比较
{
printf("拼写成功\n");
}
else
{
printf("拼写失败\n");
error++;
tail_insert_un(un_head,p);
}
}
//正确/全部 算出正确率
double result =((10-error)/10.0)*100;
printf("正确:%d ",10-error);
printf("错误:%d\n",error);
printf("您的正确率是:%lf\n",result);
}
//初始化链表来存放生词
Node* unknow_list_init()
{
Node* un_head = (Node*)malloc(sizeof(Node));//申请一个头节点空间
//判断是否申请成功
assert(un_head);
//初始化
strcpy(un_head->eng,"0");
strcpy(un_head->chi,"0");
un_head->next=NULL;
return un_head;//返回头节点
}
//还原链表,从生词本文件中读取数据到链表
int createlink1(Node* un_head)
{
//创建新的链表,将读到的数据存入链表中
//Node *head =(Node*)malloc(sizeof(Node));
Node* h = un_head;
char new_eng[50];
char new_chi[40];
Node *p=h;
Node *q=h;
FILE * r= fopen("/mnt/hgfs/share/Sep/dictionary1.txt","r");
if(r==NULL)
{
printf("打开文件失败!");
return -1;
}
while(fscanf(r,"%s %s",new_eng,new_chi)!=EOF)
{
q= (Node*)malloc(sizeof(Node));
strcpy(q->eng,new_eng);
strcpy(q->chi,new_chi);
p->next=q;
p=q;
}
p->next=NULL;
fclose(r);
// return h;
}
//尾插法向链表中放入单词
void tail_insert_un(Node* un_head,Node* p)
{
createlink1(un_head);
//开辟一个新的节点,向尾部链接
Node* new_node = (Node*)malloc(sizeof(Node));
assert(new_node);
strcpy(new_node->eng,p->eng);
strcpy(new_node->chi,p->chi);
new_node->next = NULL;
assert(un_head);//判断头指针是否为空
//定义一个临时变量p,来代替head移动
Node* pp = un_head;
//找到尾节点
while(pp->next!=NULL)
{
pp=pp->next;
}
//将添加到节点的元素追加到fp文件中
FILE* fp=fopen("/mnt/hgfs/share/Sep/dictionary1.txt","a+");
fprintf(fp,"%s %s",new_node->eng,new_node->chi);
fprintf(fp,"\n");
fclose(fp);
//尾插,连接节点
pp->next = new_node;
}
//遍历并打印整个生词本链表
int print_list_un(Node* un_head)
{
createlink1(un_head);
Node* p=un_head;
assert(p);
int count=0;
while(p->next!=NULL)
{
p=p->next;
count++;
printf("%s %s\n",p->eng,p->chi);
}
printf("%d\n",count);
return count;
}
int main()
{
Node* head = list_init();
int count = print_list1(head);
Node* un_head = unknow_list_init();//返回新建生词本链表的头指针
//createlink1(un_head);
printf("\n");
while(1)
{
printf("----------------请输入对应的功能--------------------\n");
printf("----------------1. 根据汉语查英语 ------------------\n");
printf("----------------2. 根据英语查汉语 ------------------\n");
printf("----------------3. 查看生词本-----------------------\n");
printf("----------------4. 向系统中添加单词 ----------------\n");
printf("----------------5. 背单词---------------------------\n");
printf("----------------6. 查看所有单词---------------------\n");
printf("----------------7. 退出-----------------------------\n");
printf("请输入您的操作:\n");
int input=0;
scanf("%d",&input);
switch(input)
{
case 1:search_eng(head);break;
case 2:search_chi(head);break;
case 3:print_list_un(un_head);break;
case 4:tail_insert(head);break;
case 5:rem_word(head,count,un_head);break;
case 6:print_list(head);break;
case 7:return -1;break;
default:printf("输入有误\n");
return -1;
}
}
return 0;
}