默写单词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.仔细学习版。将会讲各个函数的功能和细节。今天太晚了,明天再写。

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

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

相关文章

Gradle v8.5 笔记 - 从入门到进阶(基于 Kotlin DSL)

目录 一、前置说明 二、Gradle 启动&#xff01; 2.1、安装 2.2、初始化项目 2.3、gradle 项目目录介绍 2.4、Gradle 项目下载慢&#xff1f;&#xff08;万能解决办法&#xff09; 2.5、Gradle 常用命令 2.6、项目构建流程 2.7、设置文件&#xff08;settings.gradle.…

docker入门(三)—— 安装docker

docker 安装 环境要求 本次使用的是云服务器&#xff0c;版本是 centos&#xff0c;要求版本在3.10以上 [rootiZbp15293q8kgzhur7n6kvZ /]# uname -r 3.10.0-1160.108.1.el7.x86_64 [rootiZbp15293q8kgzhur7n6kvZ /]# cat /etc/os-release NAME"CentOS Linux" VE…

数据容器-list-Python

师从黑马程序员 列表的定义语法 注&#xff1a;列表可以一次存储多个数据&#xff0c;且可以为不同的数据类型&#xff0c;支持嵌套 my_list["itheima","chengxuyuan","python"] print(my_list) print(type(my_list))#元素类型不受限 my_list[&…

架构扩展性

架构扩展性&#xff1a;应用扩展 数据扩展 组织扩展 流程扩展 核心方法论–扩展立方体&#xff1a; x轴&#xff1a;无脑克隆 y轴&#xff1a;功能分割z轴&#xff1a;客户分割扩展立方体在应用扩展的应用&#xff1a; x轴&#xff1a;横向克隆 对于无状态的应用&#xff0c;多…

vue3封装对话框el-dialog组件

实现逻辑&#xff1a; 1、引入对话框组件&#xff1b; 2、组件使用&#xff1b; 3、点新增和编辑的时候&#xff0c;通过ref调用对话框暴漏出来的方法&#xff0c;并传值&#xff1b; 4、关闭对话框时&#xff0c;封装方法&#xff0c;重置对话框的表单和重置校验&#xff1b; …

代码随想录算法训练营第二十八天 | 93. 复原 IP 地址、78. 子集、90. 子集 II

代码随想录算法训练营第二十八天 | 93. 复原 IP 地址、78. 子集、90. 子集 II 93. 复原 IP 地址题目解法 78. 子集题目解法 90. 子集 II题目解法 感悟 93. 复原 IP 地址 题目 解法 暴力破解&#xff0c;自己初始想法加上看完题解中思想的修补 class Solution { private:vect…

Swift中 any some的作用

前言 在学习Swift ui看到一个函数返回了some view。view我可以理解那some是什么&#xff1f; //ContentView.swift struct ContentView_Previews: PreviewProvider{static var previews: some View{ContentView()} }如果你仔细看一些官方文档甚至还有any关键字&#xff0c;也…

容器数据卷

目录 一、容器数据卷概念 二、使用数据卷 2.1直接使用命令来挂载 三、实战测试 四、具名挂载和匿名挂载 4.1匿名挂载举例&#xff1a; 4.2具名挂载举例&#xff1a; 五、数据卷容器 一、容器数据卷概念 数据&#xff1f;如果数据都在容器中&#xff0c;那么容器删除&am…

使用Anthenticator验证github

下载 各应用商城都有。 准备扫描 启动应用&#xff0c;点击加号&#xff0c;选择其他账户&#xff0c;进入扫描状态。 打开github的二维码 https://github.com/settings/security 下滚&#xff1a; 如图 扫描&#xff0c;添加&#xff0c;完成

SSH服务

目录 一. 熟悉SSH服务 1.1 何为SSH协议 1.2 SSH服务优点 1.3 常见的SSH协议 1.4 SSH服务的功能 1.5 为何使用SSH服务 1.6 SSH服务的工作原理 1.6.1 公钥传输原理 1.6.2 ssh加密通讯原理 1.7 SSH服务的最佳应用场景 1.8 SSH服务远程登录的方式 1.8.1 方法一&#…

逻辑数据平台的 NoETL 之道(内含QA)

作者简介&#xff1a; 余俊&#xff0c;Aloudata 合伙人 & 技术副总裁。拥有 18 年互联网技术和大数据平台相关架构经验。作为主架构师及核心研发主导并完成了 Alibaba B2B 首个海量分布式 KV 存储系统&#xff0c;作为网站架构师负责 Aliexpress 全球买全球卖交易系统的第…

基于Springboot的船运物流管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的船运物流管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

springboot企业级抽奖项目-整体展示

项目地址 GitHub - kiorr/lottery: 企业红包雨项目 star截图q&#xff1a;3353441618可以领取资料 原型效果 前台 后台 业务分析 项目介绍 项目概述 京东的红包雨大家可能都参与过&#xff0c;在某段时间内随机发放不同的红包 本项目为一个通用的红包雨模式抽奖系统&…

全国人口密度分布数据

数据福利是专门为关注小编博客及公众号的朋友定制的&#xff0c;未关注用户不享受免费共享服务&#xff0c;已经被列入黑名单的用户和单位不享受免费共享服务。参与本号发起的数据众筹&#xff0c;向本号捐赠过硬盘以及多次转发、评论的朋友优先享有免费共享服务。 对人口数量、…

ARM开发板实现24位BMP图片缩放

ARM开发板实现24位BMP图片缩放 一、linux平台bmp图片缩放 最近想在ARM开发板实现BMP图片的缩放&#xff0c;查看了一些资料&#xff0c;大家部分理论知识可参考&#xff1a; akynazh博主 &#xff0c;这位博主程序以window平台为主进行显示&#xff0c;发现在linux平台下编译…

后端系统开发之——接口参数校验

今天难得双更&#xff0c;大家点个关注捧个场 原文地址&#xff1a;后端系统开发之——接口参数校验 - Pleasure的博客 下面是正文内容&#xff1a; 前言 在上一篇文章中提到了接口的开发&#xff0c;虽然是完成了&#xff0c;但还是缺少一些细节——传入参数的校验。 即用户…

51、CR-GCN:EEG通道拓扑结构+脑功能连接捕获EEG通道关系,用于情感识别[我处理的是原始EEG数据哦]

文章&#xff1a; CR-GCN: Channel-Relationships-Based Graph Convolutional Network for EEG Emotion Recognition 单位&#xff1a; 上海大学计算机学院、上海工业计算机、喀什大学计算机学院。提出CR-GCN&#xff0c;使用GCN的邻接矩阵提取情感数据中的特征用于分类。 2…

分布式搜索引擎elasticsearch专栏三

1.数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f; 这些手机的平均价格、最高价格、最低价格&#xff1f; 这些手机每月的销售情况如何&#xff1f; 实现这些…

【双指针】算法例题

目录 二、双指针 25. 验证回文数 ① 26. 判断子序列 ① 27. 两数之和II - 输入有序数组 ② 28. 盛最多水的容器 ② 29. 三数之和 ② 二、双指针 25. 验证回文数 ① 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一…

面试六分钟,难题显真章

职场&#xff0c;这个充满机遇与挑战的舞台&#xff0c;总会在不经意间上演着意想不到的转折。我从一家小公司转投到另一家&#xff0c;原本期待着新的工作环境和更多的发展机会&#xff0c;然而现实却给了我一个不小的打击。 新公司的加班文化&#xff0c;如同一个巨大的漩涡…