欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 一个需要引用一个Unihan表,实现unicode转拼音的c++代码

一个需要引用一个Unihan表,实现unicode转拼音的c++代码

2024/10/24 23:26:24 来源:https://blog.csdn.net/m0_47489229/article/details/140905275  浏览:    关键词:一个需要引用一个Unihan表,实现unicode转拼音的c++代码

有一个小功能是实现汉字转拼音,但是别人封装好的库都是GPL的,使用就得开源自己的代码。别的一些MIT的写的很差,实时性不好,因此,自己写一个unicode转拼音的代码,而且Unihan表也是实时更新的,比引用别人的库要好很多,实时打补丁可以更新。缺点:这个代码是读取.txt文件的东西,性能比较差,查询时间用的比较长,但是生僻字和多音字啥的都是可以查到的,后面.txt文件里面的东西需要加载到代码里面,类需要重新进行集成封装提高性能。屎山版测试代码如下:


#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <thread>  // 引入线程库
#include <chrono>  // 引入时间库
#include <iostream>
#include <string>
#include <unordered_map>
#include <iostream>
#include <string>
#include <unordered_map>// 替换字符串中的带音调字符为无音调字符,并将所有音调数字添加到字符串末尾
void replaceTonedCharacters(std::string &str) {// 定义映射表,用于将带音调的字符替换为无音调字符,并保存音调数字std::unordered_map<std::string, std::pair<std::string, int>> toneMap = {{ "ā", std::make_pair("a", 1) },{ "á", std::make_pair("a", 2) },{ "ǎ", std::make_pair("a", 3) },{ "à", std::make_pair("a", 4) },{ "ō", std::make_pair("o", 1) },{ "ó", std::make_pair("o", 2) },{ "ǒ", std::make_pair("o", 3) },{ "ò", std::make_pair("o", 4) },{ "ē", std::make_pair("e", 1) },{ "é", std::make_pair("e", 2) },{ "ě", std::make_pair("e", 3) },{ "è", std::make_pair("e", 4) },{ "ī", std::make_pair("i", 1) },{ "í", std::make_pair("i", 2) },{ "ǐ", std::make_pair("i", 3) },{ "ì", std::make_pair("i", 4) },{ "ū", std::make_pair("u", 1) },{ "ú", std::make_pair("u", 2) },{ "ǔ", std::make_pair("u", 3) },{ "ù", std::make_pair("u", 4) },{ "ǖ", std::make_pair("ü", 1) },{ "ǘ", std::make_pair("ü", 2) },{ "ǚ", std::make_pair("ü", 3) },{ "ǜ", std::make_pair("ü", 4) }};std::string tones; // 保存音调数字size_t i = 0;while (i < str.size()) {bool found = false;for (const auto &pair : toneMap) {const std::string &tone = pair.first;const std::string &replacement = pair.second.first;int toneNumber = pair.second.second;// 使用 compare 方法判断当前子串是否匹配目标字符if (str.compare(i, tone.length(), tone) == 0) {// 替换为无音调字符str.replace(i, tone.length(), replacement);// 将音调数字添加到保存音调数字的字符串tones += std::to_string(toneNumber);i += replacement.length(); // 移动到下一个字符found = true;break;}}if (!found) {++i; // 如果没有匹配,移动到下一个字符}}// 将保存的音调数字添加到字符串末尾str += tones;
}int main() {std::ifstream infile("Unihan_Readings123.txt");  // 打开输入文件if (!infile) {std::cerr << "无法打开文件 unicode_data.txt!" << std::endl;return 1;}std::string line, inputUnicode, inputKey;std::cout << "请输入Unicode码(例如:U+3433): ";std::cin >> inputUnicode;inputKey = "kHanyuPinyin";bool found = false;// 逐行读取文件内容while (std::getline(infile, line)) {std::istringstream iss(line);std::string unicode, key, value;std::cout << (line) << std::endl;// 解析每一行中的unicode码和字符1if (!(iss >> unicode >> key)) {continue;  // 如果解析失败,跳过这一行}// 检查Unicode码和字符1是否匹配用户输入if (unicode == inputUnicode && key == inputKey) {found = true;std::getline(iss, value);  // 读取第二个TAB键后的字符2std::cout << (value) << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));std::istringstream valueStream(value);std::string reading;// 使用逗号分隔字符2中的每个读音并逐个输出// 只输出:后的拼音部分std::size_t pos = value.find(':');if (pos != std::string::npos) {std::string pinyin = value.substr(pos + 1);std::cout << (pinyin) << std::endl;replaceTonedCharacters(pinyin);std::cout << pinyin << std::endl;}break;  // 找到后退出循环}}if (!found) {std::cout << "未找到对应的Unicode码和字符1。" << std::endl;}infile.close();std::cout << "按任意键继续..." << std::endl;std::cin.ignore();  // 忽略上一个输入留下的换行符std::cin.get();     // 等待用户按键getchar();return 0;}

踩坑:c++代码读取utf-8函数总是出问题,会出现乱码的情况,尝试了很多方法什么u8,tchat_w、wstring类型以及都不可以问题很大,需要将utf-8转换为 ANSI文件,.txt文件直接另存的时候有个选项,可以直接进行转换,看这部分转换浪费了半天。
如果要是不转换的话,带有音调的字母根本就完全识别不出来,key-value的方式不能够使用。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com