团队:
许郁杨 031602240
盖嘉轩 031602211
开发环境为Visual Studio 2015。
实现设计思路
因为要求后续不可修改源代码或重编译,所以这次程序应该实现的功能有两个:程序能自动识别用户输入的语言并进行查找、能从对应的语言资源文件中读取资源。下面进行具体描述:
其实之前做多语言时,我的想法是通过文件读写来实现这些功能,但是作业要求了要用Resource文件来实现,那好吧。。刚开始我看了作业里附的链接,并没有注意到Cultrueinfo。。然后就去搜索了关于实现多语言的内容,翻了好多网页却没能看懂几个。最后没办法只好去瞎折腾了。。
我试着建立了资源文件,发现vs提供的资源文件里有两个像是这次可能可以用到的,分别是程序集资源文件(.resx)和资源文件(.rc)。我两个都建立了起来。其实一开始程序集的看上去更像那么回事,但我对资源文件里的string table也很感兴趣,就搜索了一下,然后打开了新世界的大门。。
string table可以集中修改项目中的字符串,还可以插入多语言副本,只是网上的内容基本都是用于窗口,而不是控制台程序。不过这给我提供了一种思路。
因为string table的多语言副本是根据系统语言自动调用的,不符合要求,所以需要找到其他方法来实现自行调用不同语言版本的功能。不过一直没什么思路,也没查到什么可用的资料。于是我就先开始着手解决输出的问题。查找了资料,并进行了一些尝试后,我找到了一种实现输出的方法,其中有几点需要注意的:
- string table中的字符串需要用CString类进行存储;
- 所需头文件为< atlstr.h >;
- 为了解决输出中文等宽字符的问题,需要提前设置区域,如:wcout.imbue(locale("CHS"))。因为其中的"CHS"可以作为字符串存储,所以也能够便利地更改区域;
- 读取字符串的方式是CString.LoadString(字符串ID),这个ID后面会再讲到;
- 输出为wcout << (LPCTSTR)CString,其实在博客和msdn上还查到了很多方法,但是个人觉得这样已经能满足这次的需要了,而且比较简便;
在实现输出的过程中,我发现了原来string table中的字符串的ID都是用无符号整型来存储的,简单说就是一个数对应一个字符串,那么程序通过对数的处理,就能够实现对不同语言版本的字符串的转换了。我在这次的程序中是这样实现的:
首先,1-5 分别是"中文"、"English"、"日本语"等,最后一位添加"End",1000-1999用于存储中文字符串(当然这次不需要用这么多),2000-2999用于英语,以此类推。读入用户输入的语言后,通过循环查找,直到找到"End",这样就实现了程序自动识别用户输入的语言并进行查找的功能。
如果找到相应语言,就将字符串ID×1000,跳转至相应的语言资源,然后按顺序输出,从而实现了从对应的语言资源文件中读取资源的功能。
通过这种较为简单的方法,我就实现了上面提到的两个要求。不过,实际操作过程中,最让人头疼的其实是字符编码问题。对于这个我是通过设置区域,并用LPCTSTR对CString进行强制转换来解决的。关于各种各样编码的问题还是要继续学习。。
程序实现和结果测试的截图
中文
日语(瞎翻。。)
github的提交链接和提交日志截图
Git提交日志
分工和协作证据截图
分工方面,我负责了大部分代码和中文、英文的资源文件,队友负责剩余代码和其他三种语言。
作业感想
不管是用文件读写还是资源,最后都需要解决字符的编码问题,这次虽然强行做到了能够输出结果,但是对于字符编码我还有很多不了解的地方,这块我应该会在最近多进行一些学习。还有就是关于Cultureinfo类,看了一些资料后感觉很有意思,也会再学习一下这种方法。不过宿舍的锐捷基本只有在深夜才能登上msdn和GitHub,流量有点经不住了。。
参考链接
挑了些这次比较有用上的。
MSDN
- CStringT Class
- Using CString
- Basic CString Operations
- basic_string Class
- basic_string::c_str
- wcout
- basic_ios::imbue