默写单词cpp(初学者版本)

  • 笔摔坏了
  • 直接使用版:yum:
  • 仔细学习版:yum:
  • ===============
  • 1.直接使用版:yum:(文件+使用规范)
    • (1)文件
    • (2)使用规范
  • 2.仔细学习版。将会讲各个函数的功能和细节。今天太晚了,明天再写。

笔摔坏了

在一个阳光明媚的早晨,我愉快的奋笔疾书,抄写默写着单词“abandon”,喝水的时候,水性笔顺着桌子掉落到地上,我心里一紧,颤颤巍巍的弯腰捡起来,在纸上写个字,发现果然笔尖果然摔坏了。没办法,只能掏出C++primeplus,复习一下什么是类,然后运用脑袋里为数不多的知识写了一个默写单词cpp。

  • 编译环境:Visual Studio 2022

提供两个路径:

直接使用版😋

仔细学习版😋

===============

1.直接使用版😋(文件+使用规范)

(1)文件

头文件 word.h

#include<iostream>
#include<new>
#include<stdio.h>
#include<cstring>
#include <stdlib.h>
#include<time.h>
#pragma warning (disable:4996)

using namespace std;
typedef struct Word   //存储单词的类型
{
	char str_EN[20];  //英文的记录
	char str_CH[10][20];  //一个英文可能有很多中文意思
	int CHcount;   //中文翻译的个数,比如tone的英文意思有色调也有声调
	Word()
	{
		memset(str_EN, 0, sizeof str_EN);
		memset(str_CH, 0, sizeof str_CH);
		CHcount = 0;
	}
}Word;

typedef struct mWord  //记录默写错误的单词
{
	int mistake[100];
	int len;   //默写错误单词的个数
	mWord()
	{
		memset(mistake, 0, sizeof mistake);
		len = 0;
	}
}mWord;

class WordWork  //主体类
{
private:      //私有成员(单词指针,单词个数)
	Word* pp;
	mWord misword;   //默写错误的单词
	int length;  //单词个数
public:
	WordWork()  //初始化成员,为什么misword不需要初始化?实际上执行“mWord misword”这句话的时候就初始化了,mWord有自己的构造函数
	{
		pp = NULL;
		length = 0;
	};
	bool Muen();   //菜单
	bool Dynamic_GetSpace(FILE* fp);
	bool Get_inCPP();  //将单词从文件放入数组
	bool test();   //测试单词
	bool testMis();   //测试错误单词
	bool Wordcmp(char* w, int p_c);   //判断是否默写正确
	int CmpCH(const string s, int p_c);  //判断中文意思对没对
	int Get_point();   //打分
	void Print();   //打印所有单词
	void PrintMis();  //打印错误的单词
	~WordWork()   //析构函数
	{
		delete[]pp;
	}
};

bool WordWork::Dynamic_GetSpace(FILE* fp)  //动态开辟数组
{
	char temp[50];
	while (fgets(temp, 50, fp) != NULL)  //先一行一行读取单词,目的不是将单词提取出来,目的是看有多少单词,然后开辟数组
	{
		length++;
	}
	pp = new Word[length];
	for (int i = 0; i < length; i++)   //初始化单词,此时单词还没有读入,单纯开辟空间,所有待会文件指针fp需要重新指向文件开头
	{
		memset(pp[i].str_CH, 0, sizeof pp[i].str_CH);
		memset(pp[i].str_EN, 0, sizeof pp[i].str_EN);
	}
	return true;
}

int WordWork::CmpCH(const string s, int p_c)   //s是中文串,p_c是pp的下标
{

	int rightCount = 0;
	int i, j;
	for (i = 0; i < pp[p_c].CHcount; i++)//因为s只是一个中文串,即一个中文意思,那么就需要对pp对应下标的所有中文意思都进行一个判断,有一个正确就正确
	{
		for (j = 0; j < s.length(); j++)
		{
			if (s[j] != pp[p_c].str_CH[i][j])break;
		}
		if (j == s.length()) //说明s和pp[p_c].str_CH[i]完全匹配,此时注意,可能pp后面还有字符,即有可能s=="我",pp=="我是"
		{
			if (pp[p_c].str_CH[i][j] == '\0')rightCount++;
		}
	}
	return rightCount;
}

int WordWork::Get_point()  //计算得到的分数
{
	return (100 - misword.len * 2);
}

bool WordWork::Wordcmp(char* w, int p_c)  //k==1,英文   p_c表示pp的下标,w是默写的字符串
{
	if (w[0] >= 'a' && w[0] <= 'z')  //很明显默写的英文
	{
		int i = 0;
		while (w[i] != '\0' && pp[p_c].str_EN[i] != '\0' && w[i] == pp[p_c].str_EN[i])
		{
			i++;
		}
		if (w[i] != '\0' || pp[p_c].str_EN[i] != '\0')
		{
			return false;
		}
	}
	else  //默写的中文,那么可能一个单词有好几个中文意思,就需要更加复杂的判断了,这里规定有一个意思默写正确就算正确
	{
		int rightCount = 0;   //正确的中文意思个数
		string t = "";       //将字符串w复制道t,因为t是已经配置好的字符串类模板,更加好使用
		for (int i = 0; w[i] != '\0'; i++)
			t += w[i];
		//考虑到可能默写的中文有好几个意思,每个意思中间用','分隔。

		string s = "";     //s用来记录t中的某一段字符串来判断是否正确
		for (int i = 0; i < t.length(); i++)  //这里仔细看有一个小巧妙,我自己定义的遇到','表示收集完一个中文意思,但是如果没有','呢?所以for循环外面还要判断一次
		{
			if (t[i] == -93 && t[i + 1] == -84)  //遇到,表示收集完一个中文意思
			{
				rightCount += CmpCH(s, p_c);  //然后看看这个收集到的中文意思是否存在
				s = "";
				i++; //需要多一次i++,跳到t[i+1]后面,即跳过逗号
			}
			else
				s += t[i];
		}
		if (s.length() != 0)  //收集最后一个中文意思(包含两种情况,本来就只有一个意思,那么很显然自然也是最后一个。有多个意思,而这个是最后一个)
		{
			rightCount += CmpCH(s, p_c);
		}
		return rightCount == 0 ? false : true;
	}
	return true;
}

bool WordWork::Muen()
{
	int choice = 1;
	while (choice != 4)
	{
		cout << "*********1.默写单词   2.存入单词   3.打印单词    4.退出*********\n";
		cin >> choice;
		switch (choice)
		{
		case 1:
		{  //先将文件数据存入数组,然后使用哈希表和随机种子函数打乱单词,最后默写
			test();
			break;
		}
		case 2:   //读文件,按行读取文件
		{
			Get_inCPP(); //从文件获得单词到cpp程序
			break;
		}
		case 3:  //打印单词
		{
			Print();
			break;
		}
		case 4:
			break;

		default:
		{
			choice = 1;
			break;
		}
		}
	}
	return true;
}

void WordWork::Print()  //打印单词
{
	for (int i = 0; i < length; i++)
	{
		printf("(%d) %s: ", i + 1, pp[i].str_EN);
		//cout << "(" << i + 1 << ") " << pp[i].str_EN;
		for (int j = 0; j < pp[i].CHcount; j++)
		{
			if (j == pp[i].CHcount - 1)cout << pp[i].str_CH[j];
			else
				printf("%s,", pp[i].str_CH[j]);
			//cout << pp[i].str_CH[j];
		}
		cout << endl;
	}
	cout << endl;
}

void WordWork::PrintMis()  //打印错误的单词
{
	cout << "你默写错误的单词是:\n";
	for (int i = 0; i < misword.len; i++)
	{
		printf("(%d)%s:", i + 1, pp[misword.mistake[i]].str_EN);  //默写英文
		for (int j = 0; j < pp[misword.mistake[i]].CHcount - 1; j++)    //默写中文
		{
			printf("%s,", pp[misword.mistake[i]].str_CH[j]);
		}
		printf("%s\n", pp[misword.mistake[i]].str_CH[pp[misword.mistake[i]].CHcount - 1]);
	}
	cout << endl << endl;
}

bool WordWork::Get_inCPP()   //从文件中读取单词,按照行读入
{
	//(1)打开文件夹(存入单词的文件夹)
	char str[20];
	memset(str, 0, sizeof str);
	cout << "输入文件名:";
	getchar();
	cin.getline(str, 20);
	FILE* fp = fopen(str, "r+");
	rewind(fp);
	if (!fp)
	{
		cout << "文件打开失败!\n";
		return false;
	}
	if (feof(fp))
	{
		cout << "文件是空的!\n";
		return false;
	}

	//(2)开辟数组空间,用于存储文件夹内单词信息(中文意思,英文意思)
	Dynamic_GetSpace(fp);   //动态开辟空间
	rewind(fp);             //将fp重新指向文件夹起始位置
	char temp[50];
	memset(temp, 0, sizeof temp);
	int p_i = -1;			//当前行,为什么是-1,因为下面while内第一句就是p_i++,由于数组下标从0开始,所以先设置-1

	//(3)
	//每一行的规则: 英文 空格若干 中文,中文,中文 换行符"\n"

	while (fgets(temp, 50, fp) != NULL)   //按照行读入 (乱七八糟一堆,目的就是把单词存入数组以便操作)
	{
		p_i++;
		int t_i = 0;  //从文件读入单词字符
		int E_i = 0;  //英文的下标

		//区分一下,一个英文只有一个英文,但是一个英文有多个中文意思
		int C_j = 0;  //第j个中文
		int C_j_i = 0;//第j个中文下标

		//按照每一行的书写规则,一一读取字符

		while (temp[t_i] != ' ')  //空格的asciil码是32
		{
			pp[p_i].str_EN[E_i] = temp[t_i];
			E_i++;
			t_i++;
		}
		while (temp[t_i] == ' ')
			t_i++;
		while (temp[t_i] != '\0')
		{
			//说明一下:中文里面逗号的ascill码是"-93和-84"(每个中文都由两个char决定)
			while ((temp[t_i] != -93 || temp[t_i + 1] != -84) && temp[t_i] != '\n')   //只要不是遇到逗号或者换行符,就读入
			{
				pp[p_i].str_CH[C_j][C_j_i] = temp[t_i];
				C_j_i++;
				t_i++;
			}
			while (temp[t_i] == -93 && temp[t_i + 1] == -84)
			{
				t_i += 2;
				C_j++;
				C_j_i = 0;
			}
			if (temp[t_i] == '\n')
			{
				t_i++;
				C_j++;
			};
		}
		pp[p_i].CHcount = C_j;
		memset(temp, 0, sizeof temp);
	}
	if (feof(fp) != 0)  //关闭文件,用完就关
	{
		fclose(fp);
		return true;
	}
	else     //提示文件没有读完,感觉这句话不需要
	{
		fclose(fp);
		cout << "文件没有走到末尾!\n";
		return false;
	}
}

bool WordWork::test()    //用时间种子函数随机生成下标,按顺序存入哈希表,然后按照哈希表下表默写单词
{
	//时间种子
	time_t t;
	t = time(0);
	srand(t);
	//哈希表1
	int* Hash = new int[length];
	int Ha_c = 0;
	for (int i = 0; i < length; i++)Hash[i] = -1;
	//哈希表2
	int* vis = new int[length];  //vis记录哪些下标被用过
	for (int i = 0; i < length; i++)vis[i] = -1;
	for (int i = 0; i < length; i++)
	{
		int k = rand() % length;
		while (vis[k] != -1)k = (k + 1) % length;
		vis[k] = 1;
		Hash[Ha_c++] = k;
	}
	cout << "\n\n\n\n\n\n\n\n*********************!!开始默写!!*************************\n"
		<< "****************************************\n******************************************\n\n\n";
	t = time(0);   //使用随机函数来交替默写英文中文
	srand(t);
	for (int i = 0; i < length; i++)
	{
		char w[50];
		memset(w, 0, sizeof w);
		int k = rand() % 2;
		if (k == 1)  //默写英文
		{
			cout << "(" << i + 1 << "):";
			for (int j = 0; j < pp[Hash[i]].CHcount; j++)
			{
				if (j == pp[Hash[i]].CHcount - 1)cout << pp[Hash[i]].str_CH[j] << "  ";
				else
					printf("%s,", pp[Hash[i]].str_CH[j]);
				//cout << pp[i].str_CH[j];
			}
			cin >> w;
		}
		else  //默写中文
		{
			cout << "(" << i + 1 << "):" << pp[Hash[i]].str_EN << "   ";
			cin >> w;
		}
		cout << endl;
		//记录下错误的单词
		if (!Wordcmp(w, Hash[i]))  //如果单词默写错误,那么将错误的单词的下标存入misword
		{
			misword.mistake[misword.len] = Hash[i];
			misword.len++;
		}
		if (w[0] == '0')break;  //中途退出,不写了 
	}
	cout << "\n\n***********你的分数是:************\n\n************************************\n\n             " << Get_point() << endl << "\n\n************************************\n\n************************************\n\n";
	cout << endl << endl;
	testMis();
	delete[]Hash;
	delete[]vis;
	return true;

}

bool WordWork::testMis()  //默写错误的单词
{
	while (misword.len != 0)  //没有全部默写对不让走!!
	{
		PrintMis();   //先输出默写错误的单词小看一下
		time_t t;
		t = time(0);
		srand(t);
		int hash[100];
		int ha_c = 0;
		memset(hash, 0, sizeof hash);
		cout << "\n\n\n\n\n\n\n\n*********************!!开始默写错误单词!!*************************\n"
			<< "****************************************\n*********************************\n";
		for (int i = 0; i < misword.len; i++)
		{
			char w[20];
			memset(w, 0, sizeof w);
			int k = rand() % 2;
			if (k == 1)  //默写英文
			{
				cout << "(" << i + 1 << "):";
				for (int j = 0; j < pp[misword.mistake[i]].CHcount; j++)
				{
					if (j == pp[misword.mistake[i]].CHcount - 1)cout << pp[misword.mistake[i]].str_CH[j] << "  ";
					else
						printf("%s,", pp[misword.mistake[i]].str_CH[j]);
					//cout << pp[i].str_CH[j];
				}
				cin >> w;
			}
			else  //默写中文
			{
				cout << "(" << i + 1 << "):" << pp[misword.mistake[i]].str_EN << "   ";
				cin >> w;
			}
			cout << endl;
			//记录下错误的单词
			if (!Wordcmp(w, misword.mistake[i]))  //如果单词默写错误,那么将错误的单词的下标存入misword
			{
				hash[ha_c] = misword.mistake[i];
				ha_c++;
			}
		}
		for (int i = 0; i < ha_c; i++)
			misword.mistake[i] = hash[i];
		misword.len = ha_c;
		cout << "\n\n你的分数是:" << Get_point() << endl;
	}
	cout << "恭喜你全部完成今日的目标!\n\n\n";
	return true;
}

主文件 wordmain.cpp

#include"word.h"
#include<iostream>
#include<cstring>
#include <stdlib.h>
#pragma warning (disable:4996)
using namespace std;

int main()
{
	WordWork op;
	op.Muen();
	return 0;
}

(2)使用规范

首先抱歉,代码写的很乱,很难看。

1:打开项目的文件夹,在名字为项目文件名字的文件夹里面创建txt文档

在这里插入图片描述

在这里插入图片描述

2: 创建txt文档,命名day1,2,3,4,,以此类推,这是我的习惯。
在这里插入图片描述

在这里插入图片描述

3:将要默写的单词按照图中格式写进txt文档,格式是:英文+空格+中文+“,”+中文+“,”+…+换行符(回车)
4:注意逗号是中文下的逗号
5:不要添加多的符合,比如句号感叹号
6:点击保存

7:打开项目,点击运行。将会弹出这个页面:

在这里插入图片描述

8:输入数字2,输入文件名,由于之前是将txt文件放入项目文件内,所以不需要添加多余路径,这是“相对路径”。不懂什么是“相对路径”和“绝对路径”的可以取了解一下。
9:输入数字3,打印单词,看看是否有错误的填写或者可以取复习一下单词
在这里插入图片描述
10.输入数字1,默写单词
在这里插入图片描述
这里提一嘴!!!如果说不想默写那么多,可以按“0”退出默写。

再有一点,如果一个英文有多个中文意思,只要有一个是正确的将判断正确?

随后会给默写的单词打分。如果是满分将不需要重复默写,如果不是满分将会将错误的打印出来并让你重新默写直到你全对为止!

在这里插入图片描述
在这里插入图片描述

2.仔细学习版。将会讲各个函数的功能和细节。今天太晚了,明天再写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/274711.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于VMware虚拟机安装MacOS BigSur系统

这周用VMWare搞了个MacOS虚拟机&#xff0c;也算是完成初中高中时候的梦想了吧~~&#xff08;那时候我的电脑配置还很拉跨&#xff0c;带不动虚拟机&#xff09;~~ 写一篇博客记录一下&#xff0c;当然这也是yonagi04.github.io建站的第一篇新博客 准备工作&#xff08;VMWare…

c++ 常用函数 集锦 整理中

c 常用函数集锦 目录 c 常用函数集锦 1、string和wstring之间转换 2、经纬度转 xyz 值 互转 3 、获取 根目录下的文件地址 1、string和wstring之间转换 std::string convertWStringToString(std::wstring wstr) {std::string str;if (!wstr.empty()){std::wstring_convert<…

31-Java前端控制器模式(Front Controller Pattern)

Java前端控制器模式 实现范例 前端控制器模式&#xff08;Front Controller Pattern&#xff09;是用来提供一个集中的请求处理机制&#xff0c;所有的请求都将由一个单一的处理程序处理该处理程序可以做认证/授权/记录日志&#xff0c;或者跟踪请求&#xff0c;然后把请求传给…

LabVIEW NV色心频率扫描

LabVIEW NV色心频率扫描 通过LabVIEW软件开发一个能够实现对金刚石氮空位&#xff08;Nitrogen-Vacancy&#xff0c;NV&#xff09;色心的频率扫描系统。系统通过USB协议与硬件设备通信&#xff0c;对NV色心进行高精度的频率扫描&#xff0c;满足了频率在2.6 GHz到3.2 GHz范围…

云原生:重塑未来应用的基石

随着数字化时代的不断深入&#xff0c;云原生已经成为了IT领域的热门话题。它代表着一种全新的软件开发和部署范式&#xff0c;旨在充分利用云计算的优势&#xff0c;并为企业带来更大的灵活性、可靠性和效率。今天我们就来聊一聊这个热门的话题&#xff1a;云原生~ &#x1f4…

DevEco Studio 项目创建

安装DevEco Studio后开始使用&#xff0c;双击桌面DevEco Studio 快捷方式弹出界面&#xff1a; 选择Application —> Empty Ability&#xff0c;点击Next 项目配置 Project name&#xff1a;工程的名称&#xff0c;可以自定义&#xff0c;由大小写字母、数字和下划线组成。…

解锁编程潜能:ChatGPT如何革新软件开发

目录 一、背景 二、功能描述 三、总结 一、背景 在这个飞速发展的数字时代&#xff0c;软件开发的效率和质量成了衡量一个开发者能力的重要标准。随着人工智能技术的不断进步&#xff0c;越来越多的开发者开始寻找能够提升工作效率的新方法。我就是其中之一&#xff0c;最近…

【RabbitMQ | 第一篇】消息队列基础知识

文章目录 1.消息队列基础知识1.1什么是消息队列&#xff1f;1.2消息队列有什么用&#xff1f;&#xff08;结合项目说&#xff09;1.2.1异步处理1.2.2削峰/限流1.2.3降低系统耦合性1.2.4实现分布式事务 1.3消息队列的缺点1.4JMS和AMQP1.4.1 JMS的两种消息模型&#xff08;1&…

海外社交营销为什么用云手机?不用普通手机?

海外社交营销作为企业拓展海外市场的重要手段&#xff0c;正日益受到企业的青睐。云手机以其成本效益和全球性特征&#xff0c;成为海外社交营销领域的得力助手。那么&#xff0c;究竟是什么特性使得越来越多的企业选择利用云手机进行海外社交营销呢&#xff1f;下文将对此进行…

【微服务】Gateway服务网关

文章目录 1、为什么需要网关2、gateway示例1&#xff09;创建gateway服务&#xff0c;引入依赖2&#xff09;编写启动类3&#xff09;基础配置和路由规则4&#xff09;重启测试5&#xff09;网关路由流程图6&#xff09;总结 3、断言工厂4、过滤器工厂4.1.路由过滤器的种类4.2、…

[Python人工智能] 四十三.命名实体识别 (4)利用bert4keras构建Bert+BiLSTM-CRF实体识别模型

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解如何实现中文命名实体识别研究,构建BiGRU-CRF模型实现。这篇文章将继续以中文语料为主,介绍融合Bert的实体识别研究,使用bert4keras和kears包来构建Bert+BiLSTM-CRF模型。然而,该代码最终结…

unity 学习笔记 4.坐标系

下载源码 UnityPackage 目录 1.基础知识 1.1.世界坐标和局部坐标 1.2.屏幕坐标 2.坐标系转换 3.练习&#xff1a;判断鼠标单击的位置 1.基础知识 1.1.世界坐标和局部坐标 1.2.屏幕坐标 2.坐标系转换 3.练习&#xff1a;判断鼠标单击的位置 步骤&#xff1a; 将脚本挂载到小…

32串口学习

基于之前的GPIO等工程&#xff0c;后面的上手难度就简单多了&#xff0c;主要是相关寄存器的设置。 void USART1_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* config USART1 clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph…

在Ubuntu20.04(原为cuda12.0, gcc9.几版本和g++9.几版本)下先安装cuda9.0后再配置gcc-5环境

因为自己对Linux相关操作不是很熟悉&#xff0c;所以因为之前的代码报错之后决定要安cuda9.0&#xff0c;于是先安装了cuda9.0。里面用到的一些链接&#xff0c;链接文件夹时直接去copy它的路径&#xff0c;就不那么容易错了。 今天运行程序之后发现gcc环境不太匹配cuda9.0&am…

图书馆管理系统 1.架构项目以及加搭建项目

项目架构图 技术栈 后端 开发语言&#xff1a;java 开发环境&#xff1a;jdk11.0.12 开发工具&#xff1a;IntelliJ IDEA 2022.2.4 项目管理工具&#xff1a;maven 集成框架&#xff1a;springboot 权限控制框架&#xff1a;springSecurity 数据库&#xff1a;mysql 数据库框架…

Selenium不同版本配置自动下载驱动及打包细节

Selenium配置浏览器驱动 自动下载浏览器驱动的方法 selenium4.7.0自动下载浏览器驱动的方法 selenium4.11.0 或4.11.1手动设置浏览器驱动路径的方法pyinstaller打包程序时同时打包ChromeDriverchromedriver路径需要sys._MEIPASS的路径进行引用方法一&#xff1a;通过–add-data…

3、java虚拟机-类的生命周期-初始化阶段(与程序员有关)

一 、静态代码块执行顺序和字节码文件中的执行顺序以及什么赋值。 类的生命周期-初始化阶段-被static所修饰的常量才会被赋予值 初始化阶段-代码中静态代码块和静态变量的顺序和字节码中的执行顺序是一致的。 二、4种情况下&#xff0c;类会被初始化。 1、怎样查看类是…

JRTLIS登录

之前一直没做登录一是登录涉及业务&#xff0c;框架还没完成的情况不想涉及业务。二是没想好怎么提供多产品适用的登录界面。 不同产品可能登录的组是不同的&#xff0c;如&#xff1a;医生的科室、护士的病区、检验的工作组、试剂的试剂组、血库的输血科。如果登录要把大家都…

百度交易中台之系统对账篇

作者 | 天空 导读 introduction 百度交易中台作为集团移动生态战略的基础设施&#xff0c;面向收银交易与清分结算场景&#xff0c;赋能业务、提供高效交易生态搭建。目前支持百度体系内多个产品线&#xff0c;主要包括&#xff1a;度小店、小程序、地图打车、文心一言等。本文…

MNN createSession 之创建流水线后端(四)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session::resize 之流水线编码&am…
最新文章