2017第四次作业

支持多语言版本四则运算程序

队员学号和博客主页链接

031602211盖嘉轩 博客主页

031602240许郁杨 博客主页

实现设计思路

首先这次的作业两种普遍的思路。

第一种是将五种语言的翻译版本都存到txt这样的资源文件,然后再存一个目录的资源文件中,然后在代码中添加一个部分来读取这些。 一行一行地读取txt中的内容。这样就实现了在不改动代码的同时能新增加语言和删去语言。只需增加新的翻译版本的txt的资源文件。

第二种是像王源大佬那样去啃文档,调用各种API的高逼格做法(只能仰望)

而我们的做法则十分有创意(),由于我的队友十分熟练的运用visual studio,他看题后经过几次尝试,发现我们可以把字符串和值放入visual studio原有的段-stringtable中。具体过程如下:

首先使用 Visual Studio 的资源编辑器创建一个字符串,然后给每一个字符串取一个ID,一般给它取名字都以 IDS_开头。然后用lordstring方法,LoadString 方法需要一个字符串资源的 ID 作为参数,然后它从 STRINGTABLE 中取出它对应的字符串,赋值给 CString 对象。并且最好设置两个字符串,一个读,一个写。

有些小伙伴可能会想:这怎么可能工作呢。怎么能把 STRINGTABLE ID 转化成一个指针呢。很简单:所有的字符串 ID 都在1~65535这个范围内,也就是说,它所有的高位都是0,而在程序中所使用的指针是不可能小于65535的,因为程序的低 64K 内存永远也不可能存在的,如果试图访问0x00000000到0x0000FFFF之间的内存,将会引发一个内存越界错误。所以说1~65535的值不可能是一个内存地址,所以可以用这些值来作为字符串资源的ID。

然后把不同的翻译文件放在不同的资源文件中,一个一个检测就可以了

还要注意的是,大多数的方法即可以接受一个 UINT 型的参数,也可以接受一个 LPCTSTR 型的参数,这是依赖 C++ 的重载功能做到的。C++重载函数带来的 弊端就是造成所有的强制类型转化都需要显示声明。同样,也可以给很多种结构只传递一个资源名。

程序实现和结果测试的截图

以下是这次作业的主要代码

/*************************************************************
文件名:head.h
作者:盖嘉轩 许郁杨 日期:2017/03/14
描述: 头文件
*************************************************************/

#pragma once
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<sstream>
#include<cmath>
#include<ctime>
#include<vector>
#include<stack>
#include<cassert>
#include<atlstr.h>
#define Min(x,y) (((x)<(y))?(x):(y))
#define Max(x,y) (((x)>(y))?(x):(y))
#define random(a,b) (rand()%(b-a+1)+a)   
#define MAX 1000
using namespace std;

/*generate.cpp*/
int getRand(int down, int up);
void getAndCalculate(int num, int low, int high, int flag0, char flag1, char flag2, char flag3);

/*Stack.cpp*/
void transEquation(string infix, char postfix[]);
string countEquation(string infix);

/*verify.cpp*/
bool ifOnly(string str, vector<string> se);
void checkAndOutput(string equ, int n, string result);
void finalOut();

/*fraction.cpp*/
class Fraction
{
private:
	int numerator, denominator;
	string numerators, denominators;
	int greatestCommonDivisor(int x, int y);

public:
	Fraction();
	Fraction(int numerator, int denominator);
	Fraction getFrac(int l, int h);
	bool checkZero(Fraction frac);
	bool checkInt(Fraction frac);
	Fraction transFrac(int up, int down);

	Fraction simplify(Fraction frac);
	string transString(Fraction frac);
	string transToString(Fraction frac);

	friend const Fraction operator +(Fraction frac1, Fraction frac2);
	friend const Fraction operator -(Fraction frac1, Fraction frac2);
	friend const Fraction operator *(Fraction frac1, Fraction frac2);
	friend const Fraction operator /(Fraction frac1, Fraction frac2);
};
/*************************************************************
文件名:main.cpp
作者:盖嘉轩 许郁杨 日期:2017/03/14
描述: 初始界面
主要功能包括:语言切换、功能选择
*************************************************************/

#include"head.h"
UINT idValue;

int main()
{
	int i, j, k, num, low, high, flag0, tmp;
	char flag1, flag2, flag3;
	CString langName, langList, langStr;
	string Lang;

	wcout.imbue(locale("CHS"));
	cout << "Which language you would like to choose?\n";
	i = 1;
	idValue = 0;
	langList.LoadString(++idValue);
	while (langList != "End")
	{
		cout << i << '.';
		wcout << (LPCTCH)langList << endl;
		i++;
		langList.LoadString(++idValue);
	}
	cout << "Please input the name of the language:";
	
	tmp = 0;
	idValue = 0;
	while (tmp == 0)
	{	
		char tmpc[MAX];
		fgets(tmpc, MAX, stdin);
		stringstream tmpcs;
		tmpcs << tmpc;
		tmpcs >> Lang;
		langName = Lang.c_str();
		langList.LoadString(++idValue);
		while (langList != "End")
		{
			if (langList == langName)
			{
				tmp = 1;
				idValue *= 1000;
				break;
			}
			langList.LoadString(++idValue);
		}
		if (tmp == 0)
		{
			idValue = 1;
			cout << "Sorry, please choose other language:";
		}
	}

	langStr.LoadString(idValue);
	wcout << endl << (LPCTSTR)langStr;
	cin >> num;

	langStr.LoadString(++idValue);
	wcout << (LPCTSTR)langStr;
	cin >> low >> high;

	langStr.LoadString(++idValue);
	wcout << (LPCTSTR)langStr;
	cin >> flag0;

	langStr.LoadString(++idValue);
	wcout << (LPCTSTR)langStr;
	cin >> flag1;

	langStr.LoadString(++idValue);
	wcout << (LPCTSTR)langStr;
	cin >> flag2;

	langStr.LoadString(++idValue);
	wcout << (LPCTSTR)langStr;
	cin >> flag3;

	idValue++;

	cout << endl << "********************************************************************" << endl;
	cout << "                                                                    " << endl;

	getAndCalculate(num, low, high, flag0, flag1, flag2, flag3);
	return 0;
}
/*************************************************************
文件名:verify.cpp
作者:盖嘉轩 许郁杨 日期:2017/03/14
描述: 检验和输出结果
主要功能包括:判重、检验答案、输出答案
*************************************************************/

#include"head.h"
extern UINT idValue;

int correct = 0, wrong = 0;
bool ifOnly(string str, vector<string> se) //判断表达式是否重复 
{
	int count = 0;
	for (int i = 0; i<se.size(); i++)
	{
		if (str != se[i]) count++;
		else break;
	}
	if (count == se.size()) return true;
	else return false;
}
void checkAndOutput(string equ, int n, string result) //检验答案并输出正确答案 
{
	string ans;
	CString str;
	cout << "(" << n << ") " << equ << "=";
	wcout.imbue(locale("CHS"));
	cin >> ans;
	if (ans == result)
	{
		str.LoadString(idValue);
		wcout << (LPCTSTR)str << endl;
		correct++;
	}
	else
	{
		str.LoadString(idValue + 1);
		wcout << (LPCTSTR)str;
		cout << result << endl;
		wrong++;
	}
	cout << endl;
}
void finalOut() //输出正误个数 
{
	CString str;
	cout << "********************************************************************" << endl;
	cout << endl;
	wcout.imbue(locale("CHS"));
	str.LoadString(++idValue);
	wcout << (LPCTSTR)str;
	cout << correct << endl;
	str.LoadString(++idValue);
	wcout << (LPCTSTR)str;
	cout << wrong;
}

以下是测试截图

git

由于这次我在做好文件之后才发现我不小心建了一个新的库,没办法与之前的develop合并,而且马上要提交博客了,所以我把文件传给了我的队友,由他提交。所以这次没有我的提交记录。(这次的失误充分说明我git还是不熟悉,我决定把之前的库删了,重新再创建一个,把整个流程再走一遍)

分工合作

这次主要是由我的队友提供的灵感,我负责 francais deutsch 日本语 这三个文件和 main.cpp中的部分代码,我的队友负责main。cpp和verify。cpp的大部分代码。

差异部分

作业感想

说真的,每次做作业的发现自己不会的东西特别多,每次都要上网百度很长时间,而且还看不懂。但是这次学习之后发现自己的学习理解能力较以前有提高,即使在完全不懂的情况下也可以“啃文档”,虽然还不能像我的队友和我们班的各位大佬那样自学能力超强,但是感觉没有那么难了,对于新的知识,即使完全不懂,也没那么抵触了。

而且这次才发现模块化编程的好处了,因为当时将不同的功能都分类了,所以这次只需要改两个文件-main.cpp和verify.cpp就可以了。而且我们的程序明显在模块化这方面有很大的提升空间。

参考链接

CString搜狗百科

posted @ 2017-03-15 20:22  031602211  阅读(503)  评论(2编辑  收藏  举报