目录
前言
该词典为本人进行日语学习使用,其他语言版本可根据该版本进行修改。这篇文章是我的处女作,若有不足,请各位大佬帮忙指正。
需求分析
作为词典,最主要的功能无非“增删查”。在此基础上,我还添加了“背”的功能。由于是文件储存版本,因此我还在此基础上增加了“保存”的功能。
代码编写
框架搭建
首先先写程序主体。利用do...while循环,当选择“0”时退出程序。再用swicht语句实现程序主题。
在这里,我将程序分成了3部分(程序主体program.c、功能实现func.c和功能头文件func.h)。
小技巧:利用枚举常量“代替”各个功能名,便于后续程序的编写。
enum { EXIT, ADD, SEARCH, DEL, SHOW, RECITE, SAVE }
此时,program.c的代码如下:
#include"fun.h"
int main()
{
int input = 0;
do
{
scanf("%d", &input);
switch (input)
{
case ADD:
break;
case SEARCH:
break;
case DEL:
break;
case SHOW:
break;
case RECITE:
break;
case SAVE:
break;
case EXIT:
break;
default:
break;
}
} while (input);
return 0;
}
菜单、退出程序
调用多个printf()函数将菜单打印出来。退出程序时,调用一个printf()函数提示已经退出程序。
此时,program.c如下:
#include"fun.h"
int main()
{
int input = 0;
do
{
menu1();
switch (input)
{
case ADD:
break;
case SEARCH:
break;
case DEL:
break;
case SHOW:
break;
case RECITE:
break;
case SAVE:
break;
case EXIT:
printf("已退出\n");
break;
default:
break;
}
} while (input);
return 0;
}
func.c如下:
#include"fun.h"
void menu1()//无返回值
{
printf("**** 1. 添加单词*** 2. 查找单词 ****\n");
printf("**** 3. 删除单词*** 4. 展示单词表****\n");
printf("**** 5. 背单词 *** 6. 保存 ****\n");
printf("*****0. 退出 *********************\n");
printf("请选择:");
}
func.h如下:
#pragma once
#include<stdio.h>
void menu1();
词典的创建和初始化
首先先创建词典。先用结构体定义一个单词,单词包含单词本体、假名和中文意思。
#define word_length 30//定义单词本体、假名和中文意思的最大长度
typedef struct word
{
char character[word_length];
char kana[word_length];
char chinese[word_length];
}word;
再用另一个结构体定义单词表,单词表包含单词、当前单词数量和当前单词表最大数量。
typedef struct wordlist
{
word* list;//这里使用指针,便于后续初始化和增容
int size;//记录目前的单词数量
int cap;//记录目前的单词表最大数量
int num;//记录存储的单词数量
}wordlist;
在初始化过程中,使用calloc()函数进行初始化,并将单词都初始化为0。
注意:在程序结束后要调用free()函数将单词表的空间释放。
void InitList(wordlist* ps)
{
ps->list=(word* )calloc(init_cap, sizeof(word));
if (ps->list == NULL)
{
return;
}
ps->size = 0;
ps->cap = init_cap;
}
此时,program.c如下:
#include"func.h"
int main()
{
int input = 0;
wordlist List;
InitList(&List);//这里将单词表的地址传递进函数,可以节省内存空间,效率更高。后面的功能同理。
do
{
printf("当前单词数量:%d 当前单词最大数量:%d\n", List.size, List.cap);
menu1();
scanf("%d", &input);
switch (input)
{
case ADD:
break;
case SEARCH:
break;
case DEL:
break;
case SHOW:
break;
case RECITE:
break;
case SAVE:
break;
case EXIT:
printf("已退出\n");
break;
default:
break;
}
} while (input);
free(List.list);
List.list == NULL;
return 0;
}
func.c如下:
#include"func.h"
void menu1()
{
printf("**** 1. 添加单词*** 2. 查找单词 ****\n");
printf("**** 3. 删除单词*** 4. 展示单词表****\n");
printf("**** 5. 背单词 *** 6. 保存 ****\n");
printf("*****0. 退出 *********************\n");
printf("请选择:");
}
void InitList(wordlist* ps)
{
ps->list=(word* )calloc(init_cap, sizeof(word));
if (ps->list == NULL)
{
return;
}
ps->size = 0;
ps->cap = init_cap;
}
fun.h如下:
#pragma once
#include<stdio.h>
#define word_length 30
#define init_cap 3//初始单词表最大容量
typedef struct word
{
char character[word_length];
char kana[word_length];
char chinese[word_length];
}word;
typedef struct wordlist
{
word* list;
int size;//记录目前的单词数量
int cap;//记录目前的单词表最大数量
int num;//记录存储的单词数量
}wordlist;
enum
{
EXIT,
ADD,
SEARCH,
DEL,
SHOW,
RECITE,
SAVE
};
void menu1();
void InitList(wordlist* ps);
增删查和展示
再增加之前要进行容量的检查。若单词表已满,则需要扩容。
删除功能和查找功能有相通之处,即先要找到目标的下标,在进行后续操作(删除或显示)。
在这里,我将查找分了三类,但每种查找的思路都相同。
展示功能能将单词表全部打印到屏幕上,因此无需查找。
在增容功能中 调用 realloc()函数,将单词表的容量扩大。
此时,program.c如下:
#include"func.h"
int main()
{
int input = 0;
wordlist List;
InitList(&List);
do
{
printf("当前单词数量:%d 当前单词最大数量:%d\n", List.size, List.cap);
menu1();
scanf("%d", &input);
switch (input)
{
case ADD:
AddWord(&List);
break;
case SEARCH:
SearchWord(&List);
break;
case DEL:
DelWord(&List);
break;
case SHOW:
ShowList(&List);
break;
case RECITE:
break;
case SAVE:
break;
case EXIT:
printf("已退出\n");
break;
default:
break;
}
} while (input);
free(List.list);
List.list == NULL;
return 0;
}
func.c如下:
#include"func.h"
void menu1()
{
printf("**** 1. 添加单词*** 2. 查找单词 ****\n");
printf("**** 3. 删除单词*** 4. 展示单词表****\n");
printf("**** 5. 背单词 *** 6. 保存 ****\n");
printf("*****0. 退出 *********************\n");
printf("请选择:");
}
void InitList(wordlist* ps)
{
ps->list=(word* )calloc(init_cap, sizeof(word));
if (ps->list == NULL)
{
return;
}
ps->size = 0;
ps->cap = init_cap;
}
void AddSpace(wordlist* tmp)
{
tmp->list = realloc(tmp->list, (tmp->cap + add_cap) * sizeof(word));
if (tmp->list != NULL)
{
printf("增容成功\n");
}
else
perror("增容失败\n");
tmp->cap = tmp->cap + add_cap;
}
void AddWord(wordlist* ps)
{
system("cls");
if (ps->size == ps->cap)
AddSpace(ps);
printf("请输入单词:");
scanf("%s", ps->list[ps->size].character);
printf("请输入假名:");
scanf("%s", ps->list[ps->size].kana);
printf("请输入中文:");
scanf("%s", ps->list[ps->size].chinese);
ps->size++;
}
void ShowList(wordlist* ps)
{
system("cls");
int i = 0;
if (ps->size == NULL)
{
printf("单词表为空\n");
return;
}
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
for (i = 0; i < ps->size; i++)
printf("%-30s\t%-30s\t%-30s\n", ps->list[i].character, ps->list[i].kana, ps->list[i].chinese);
}
}
void menu2()
{
printf("1.通过单词查找\n");
printf("2.通过假名查找\n");
printf("3.通过中文查找\n");
printf("4.返回\n");
}
void search1(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词:");
char word_tmp[word_length] = { 0 };
scanf("%s", word_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].character, word_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词的假名\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void search2(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词的中文:");
char kana_tmp[word_length] = { 0 };
scanf("%s", kana_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].kana, kana_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void search3(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词:");
char chinese_tmp[word_length] = { 0 };
scanf("%s", chinese_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].kana, chinese_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void SearchWord(wordlist* ps)
{
system("cls");
int inpu;
menu2();
scanf("%d", &inpu);
switch (inpu)
{
case 1:
search1(ps);
break;
case 2:
search2(ps);
break;
case 3:
search3(ps);
break;
case 4:
return;
break;
default:
break;
}
return;
}
void DelWord(wordlist* ps)
{
system("cls");
int i = 0;
printf("请输入要删除的单词:");
char word_tmp[word_length] = { 0 };
scanf("%s", word_tmp);
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(ps->list[i].character, word_tmp))
{
break;
}
}
for (int j = i; j < ps->size-1; j++)
ps->list[j] = ps->list[j + 1];
ps->size--;
}
func.h 如下:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define word_length 30
#define init_cap 3//初始单词表最大容量
#define add_cap 2//每次增容时增加的容量
typedef struct word
{
char character[word_length];
char kana[word_length];
char chinese[word_length];
}word;
typedef struct wordlist
{
word* list;
int size;//记录目前的单词数量
int cap;//记录目前的单词表最大数量
int num;//记录存储的单词数量
}wordlist;
enum
{
EXIT,
ADD,
SEARCH,
DEL,
SHOW,
RECITE,
SAVE
};
void menu1();
void InitList(wordlist* ps);
void AddWord(wordlist* ps);
void ShowList(wordlist* ps);
void SearchWord(wordlist* ps);
void DelWord(wordlist* ps);
背和保存
这里我将背也分成了三部分,但每一个部分的内核相同。
关于保存,及要能手动保存,也要能在退出前保存。在程序开始时,要能从文件中读取信息,因此还要在初始化中增加“加载”功能。
这两个功能代码如下:
void menu3()
{
printf("1.通过单词背中文\n");
printf("2.通过假名背中文\n");
printf("3.通过中文背单词\n");
printf("4.返回\n");
}
void recite1(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].character);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.chinese, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void recite2(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].kana);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.chinese, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void recite3(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].chinese);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.character, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void ReciteWord(wordlist* ps)
{
system("cls");
int inpu;
menu3();
scanf("%d", &inpu);
switch (inpu)
{
case 1:
recite1(ps);
break;
case 2:
break;
case 3:
break;
case 4:
return;
break;
default:
break;
}
}
//可以改成循环的版本
void LoadWordlist(wordlist* ps);
void AddSpace(wordlist* tmp);//读取过程中可能读取的数量大于初始值,因此要增容。
void InitList(wordlist* ps)
{
ps->list=(word* )calloc(init_cap, sizeof(word));
if (ps->list == NULL)
{
return;
}
ps->size = 0;
ps->cap = init_cap;
LoadWordlist(ps);
ps->num = ps->size;
}
void LoadWordlist(wordlist* ps)
{
word tmp = { 0 };
FILE* pfRead = fopen("words_list.dat", "rb");//采用“dat“的文件后缀名,防止用记事本打开后乱码。
if (pfRead == NULL)
{
perror("读文件失败");
return;
}
while (fread(&tmp, sizeof(word), 1, pfRead))
{
if (ps->size == ps->cap)
{
AddSpace(ps);
}
ps->list[ps->size] = tmp;
ps->size++;
}
fclose(pfRead);
pfRead = NULL;
}
void SaveList(wordlist* ps)
{
FILE* pfWrite = fopen("words_list.dat", "wb");
if (pfWrite == NULL)
{
perror("打开文件失败");
return;
}
for (int i = ps->num; i < ps->size; i++)
{
fwrite(&(ps->list[i]), sizeof(word), 1, pfWrite);
printf("已保存\n");
}
fclose(pfWrite);
pfWrite = NULL;
}
这里我在单词表的结构体中加了一个变量num来记录已存储的单词数,防止重复存储。
总体代码
func.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define word_length 30
#define init_cap 3
#define add_cap 2
typedef struct word
{
char character[word_length];
char kana[word_length];
char chinese[word_length];
}word;
typedef struct wordlist
{
word* list;
int size;//记录目前的单词数量
int cap;//记录目前的单词表最大数量
int num;//记录存储的单词数量
}wordlist;
enum
{
EXIT,
ADD,
SEARCH,
DEL,
SHOW,
RECITE,
SAVE
};
void menu1();
void InitList(wordlist* ps);
void AddWord(wordlist* ps);
void ShowList(wordlist* ps);
void SearchWord(wordlist* ps);
void DelWord(wordlist* ps);
void ReciteWord(wordlist* ps);
void SaveList(wordlist* ps);#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define word_length 30
#define init_cap 3
#define add_cap 2
typedef struct word
{
char character[word_length];
char kana[word_length];
char chinese[word_length];
}word;
typedef struct wordlist
{
word* list;
int size;//记录目前的单词数量
int cap;//记录目前的单词表最大数量
int num;//记录存储的单词数量
}wordlist;
enum
{
EXIT,
ADD,
SEARCH,
DEL,
SHOW,
RECITE,
SAVE
};
void menu1();
void InitList(wordlist* ps);
void AddWord(wordlist* ps);
void ShowList(wordlist* ps);
void SearchWord(wordlist* ps);
void DelWord(wordlist* ps);
void ReciteWord(wordlist* ps);
void SaveList(wordlist* ps);
func.c
#include"func.h"
void menu1()
{
printf("**** 1. 添加单词*** 2. 查找单词 ****\n");
printf("**** 3. 删除单词*** 4. 展示单词表****\n");
printf("**** 5. 背单词 *** 6. 保存 ****\n");
printf("*****0. 退出 *********************\n");
printf("请选择:");
}
void LoadWordlist(wordlist* ps);
void AddSpace(wordlist* tmp);
void InitList(wordlist* ps)
{
ps->list=(word* )calloc(init_cap, sizeof(word));
if (ps->list == NULL)
{
return;
}
ps->size = 0;
ps->cap = init_cap;
LoadWordlist(ps);
ps->num = ps->size;
}
void LoadWordlist(wordlist* ps)
{
word tmp = { 0 };
FILE* pfRead = fopen("words_list.dat", "rb");
if (pfRead == NULL)
{
perror("读文件失败");
return;
}
while (fread(&tmp, sizeof(word), 1, pfRead))
{
if (ps->size == ps->cap)
{
AddSpace(ps);
}
ps->list[ps->size] = tmp;
ps->size++;
}
fclose(pfRead);
pfRead = NULL;
}
void AddSpace(wordlist* tmp)
{
tmp->list = realloc(tmp->list, (tmp->cap + add_cap) * sizeof(word));
if (tmp->list != NULL)
{
printf("增容成功\n");
}
else
perror("增容失败\n");
tmp->cap = tmp->cap + add_cap;
}
void AddWord(wordlist* ps)
{
system("cls");
if (ps->size == ps->cap)
AddSpace(ps);
printf("请输入单词:");
scanf("%s", ps->list[ps->size].character);
printf("请输入假名:");
scanf("%s", ps->list[ps->size].kana);
printf("请输入中文:");
scanf("%s", ps->list[ps->size].chinese);
ps->size++;
}
void ShowList(wordlist* ps)
{
system("cls");
int i = 0;
if (ps->size == NULL)
{
printf("单词表为空\n");
return;
}
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
for (i = 0; i < ps->size; i++)
printf("%-30s\t%-30s\t%-30s\n", ps->list[i].character, ps->list[i].kana, ps->list[i].chinese);
}
}
void menu2()
{
printf("1.通过单词查找\n");
printf("2.通过假名查找\n");
printf("3.通过中文查找\n");
printf("4.返回\n");
}
void search1(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词:");
char word_tmp[word_length] = { 0 };
scanf("%s", word_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].character, word_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词的假名\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void search2(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词的中文:");
char kana_tmp[word_length] = { 0 };
scanf("%s", kana_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].kana, kana_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void search3(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词:");
char chinese_tmp[word_length] = { 0 };
scanf("%s", chinese_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].kana, chinese_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void SearchWord(wordlist* ps)
{
system("cls");
int inpu;
menu2();
scanf("%d", &inpu);
switch (inpu)
{
case 1:
search1(ps);
break;
case 2:
search2(ps);
break;
case 3:
search3(ps);
break;
case 4:
return;
break;
default:
break;
}
return;
}
void DelWord(wordlist* ps)
{
system("cls");
int i = 0;
printf("请输入要删除的单词:");
char word_tmp[word_length] = { 0 };
scanf("%s", word_tmp);
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(ps->list[i].character, word_tmp))
{
break;
}
}
for (int j = i; j < ps->size-1; j++)
ps->list[j] = ps->list[j + 1];
ps->size--;
}
void menu3()
{
printf("1.通过单词背中文\n");
printf("2.通过假名背中文\n");
printf("3.通过中文背单词\n");
printf("4.返回\n");
}
void recite1(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].character);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.chinese, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void recite2(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].kana);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.chinese, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void recite3(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].chinese);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.character, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void ReciteWord(wordlist* ps)
{
system("cls");
int inpu;
menu3();
scanf("%d", &inpu);
switch (inpu)
{
case 1:
recite1(ps);
break;
case 2:
break;
case 3:
break;
case 4:
return;
break;
default:
break;
}
}
void SaveList(wordlist* ps)
{
FILE* pfWrite = fopen("words_list.dat", "wb");
if (pfWrite == NULL)
{
perror("打开文件失败");
return;
}
for (int i = ps->num; i < ps->size; i++)
{
fwrite(&(ps->list[i]), sizeof(word), 1, pfWrite);
printf("已保存\n");
}
fclose(pfWrite);
pfWrite = NULL;
}#include"func.h"
void menu1()
{
printf("**** 1. 添加单词*** 2. 查找单词 ****\n");
printf("**** 3. 删除单词*** 4. 展示单词表****\n");
printf("**** 5. 背单词 *** 6. 保存 ****\n");
printf("*****0. 退出 *********************\n");
printf("请选择:");
}
void LoadWordlist(wordlist* ps);
void AddSpace(wordlist* tmp);
void InitList(wordlist* ps)
{
ps->list=(word* )calloc(init_cap, sizeof(word));
if (ps->list == NULL)
{
return;
}
ps->size = 0;
ps->cap = init_cap;
LoadWordlist(ps);
ps->num = ps->size;
}
void LoadWordlist(wordlist* ps)
{
word tmp = { 0 };
FILE* pfRead = fopen("words_list.dat", "rb");
if (pfRead == NULL)
{
perror("读文件失败");
return;
}
while (fread(&tmp, sizeof(word), 1, pfRead))
{
if (ps->size == ps->cap)
{
AddSpace(ps);
}
ps->list[ps->size] = tmp;
ps->size++;
}
fclose(pfRead);
pfRead = NULL;
}
void AddSpace(wordlist* tmp)
{
tmp->list = realloc(tmp->list, (tmp->cap + add_cap) * sizeof(word));
if (tmp->list != NULL)
{
printf("增容成功\n");
}
else
perror("增容失败\n");
tmp->cap = tmp->cap + add_cap;
}
void AddWord(wordlist* ps)
{
system("cls");
if (ps->size == ps->cap)
AddSpace(ps);
printf("请输入单词:");
scanf("%s", ps->list[ps->size].character);
printf("请输入假名:");
scanf("%s", ps->list[ps->size].kana);
printf("请输入中文:");
scanf("%s", ps->list[ps->size].chinese);
ps->size++;
}
void ShowList(wordlist* ps)
{
system("cls");
int i = 0;
if (ps->size == NULL)
{
printf("单词表为空\n");
return;
}
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
for (i = 0; i < ps->size; i++)
printf("%-30s\t%-30s\t%-30s\n", ps->list[i].character, ps->list[i].kana, ps->list[i].chinese);
}
}
void menu2()
{
printf("1.通过单词查找\n");
printf("2.通过假名查找\n");
printf("3.通过中文查找\n");
printf("4.返回\n");
}
void search1(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词:");
char word_tmp[word_length] = { 0 };
scanf("%s", word_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].character, word_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词的假名\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void search2(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词的中文:");
char kana_tmp[word_length] = { 0 };
scanf("%s", kana_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].kana, kana_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void search3(wordlist* tmp)
{
int i = 0;
printf("请输入要查找的单词:");
char chinese_tmp[word_length] = { 0 };
scanf("%s", chinese_tmp);
for (i = 0; i < tmp->size; i++)
{
if (0 == strcmp(tmp->list[i].kana, chinese_tmp))
{
break;
}
}
if (i == tmp->size)
printf("未找到所查单词\n");
else
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", tmp->list[i].character, tmp->list[i].kana, tmp->list[i].chinese);
}
}
void SearchWord(wordlist* ps)
{
system("cls");
int inpu;
menu2();
scanf("%d", &inpu);
switch (inpu)
{
case 1:
search1(ps);
break;
case 2:
search2(ps);
break;
case 3:
search3(ps);
break;
case 4:
return;
break;
default:
break;
}
return;
}
void DelWord(wordlist* ps)
{
system("cls");
int i = 0;
printf("请输入要删除的单词:");
char word_tmp[word_length] = { 0 };
scanf("%s", word_tmp);
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(ps->list[i].character, word_tmp))
{
break;
}
}
for (int j = i; j < ps->size-1; j++)
ps->list[j] = ps->list[j + 1];
ps->size--;
}
void menu3()
{
printf("1.通过单词背中文\n");
printf("2.通过假名背中文\n");
printf("3.通过中文背单词\n");
printf("4.返回\n");
}
void recite1(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].character);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.chinese, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void recite2(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].kana);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.chinese, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void recite3(wordlist* tmp)
{
int i = rand() % (tmp->size);
printf("%s\n", tmp->list[i].chinese);
int a = 0;
word ret = tmp->list[i];
char word_tmp[word_length];
do
{
printf("请输入中文意思(错误3次直接看答案):");
scanf("%s", word_tmp);
if (0 == strcmp(ret.character, word_tmp))
{
printf("回答正确\n");
break;
}
a++;
if (a == 3)
{
printf("%-30s\t%-30s\t%-30s\n", "单词", "假名", "中文意思");
printf("%-30s\t%-30s\t%-30s\n", ret.character, ret.kana, ret.chinese);
break;
}
printf("回答错误,请重试\n");
} while (a != 3);
}
void ReciteWord(wordlist* ps)
{
system("cls");
int inpu;
menu3();
scanf("%d", &inpu);
switch (inpu)
{
case 1:
recite1(ps);
break;
case 2:
break;
case 3:
break;
case 4:
return;
break;
default:
break;
}
}
void SaveList(wordlist* ps)
{
FILE* pfWrite = fopen("words_list.dat", "wb");
if (pfWrite == NULL)
{
perror("打开文件失败");
return;
}
for (int i = ps->num; i < ps->size; i++)
{
fwrite(&(ps->list[i]), sizeof(word), 1, pfWrite);
printf("已保存\n");
}
fclose(pfWrite);
pfWrite = NULL;
}
program.c
#include"func.h"
int main()
{
int input = 0;
wordlist List;
InitList(&List);
srand((unsigned int)time(NULL));
do
{
printf("当前单词数量:%d 当前单词最大数量:%d\n", List.size, List.cap);
menu1();
scanf("%d", &input);
switch (input)
{
case ADD:
AddWord(&List);
break;
case SEARCH:
SearchWord(&List);
break;
case DEL:
DelWord(&List);
break;
case SHOW:
ShowList(&List);
break;
case RECITE:
ReciteWord(&List);
break;
case SAVE:
SaveList(&List);
break;
case EXIT:
SaveList(&List);
printf("已退出\n");
break;
default:
break;
}
} while (input);
free(List.list);
List.list == NULL;
return 0;
}
我已经将源码发到我的Github上了。链接:xwz639-739/worddictionary (github.com)
可能与当前代码有出入,以这一版为准。