程序所用文檔如圖,我需要處理這些數據,把它變成
我的代碼是這樣的
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include <cstdlib>
using namespace std;
bool isLetterOrNumber(const char &word);
bool isChinese(const char &word);
int main(int argc, char* argv[])
{
// 首先要打開這個文件,用二進制形式
ifstream ifs("list_t.txt", ios::binary);
// 需要把結果寫入一個目標文件
ofstream ofs("hz_pinyin.txt", ios::binary);
// 需要一個臨時存儲字符
char word;
// 需要一個字符串存拼音
string pinyin;
// 需要一個字符串存漢字
string chinese;
// 我們需要通過漢字來檢索拼音,所以需要一個從string到string的map
map<string, string> table;
// 錯誤處理,如果ifs指向NULL,結束程序
if (!ifs)
{
cerr << "文件打開錯誤,請檢查" << endl;
exit(0);
}
// 打開文件後看見了下面這一行
// a1 阿啊锕呵吖腌錒
// 文件指針開始移動
while (!ifs.eof())
{
// 先讀取當前位置的字符
ifs.read((char*)&word, 1);
// 判斷讀到的字符是不是英文字符和數字(因為拼音是由英文字符和數字組成的)
if (isLetterOrNumber(word)) // 錒的後一個字節內容是48h,到這一句會判斷為真,連入pinyin,造成後面亂碼
// 放入pinyin字符串
pinyin += word;
// 判斷讀到的字符是不是中文
else if (isChinese(word))
{
// 放入chinese字符串
chinese += word;
// 判斷中文字符串長度是否為2,如果為2,chinese為索引,pinyin為對應值,存入map
if (chinese.size() == 2)
{
table[chinese] = pinyin;
// 以<中文><拼音>形式存入新的文件
ofs.write(chinese.c_str(), chinese.size());
ofs.write(pinyin.c_str(), pinyin.size());
// 接著清空chinese字符串,以迎接下一個漢字
chinese.clear();
// 往目標文件寫入一個回車
ofs.write("\r", 1);
// 往目標文件寫入一個換行
ofs.write("\n", 1);
}
}
// 如果讀到了0x0D,那麼清空pinyin字符串,並接著讀一個0x0A
else if (word == 0x0D)
{
pinyin.clear();
ifs.read((char*)&word, 1);
}
}
ifs.close();
ofs.close();
return 0;
}
bool isLetterOrNumber(const char &word)
{
if ((word >= '0' && word <= '9') || (word >= 'a' && word <= 'z')
|| (word >= 'A' && word <= 'Z'))
return true;
return false;
}
bool isChinese(const char &word)
{
if ((!isLetterOrNumber(word)) && (word != ' ') && (word != '\r')
&& (word != '\n'))
return true;
return false;
}
生成的結果是亂碼。我用winhex查看了一下,問題發生在“錒”這個字上。錒的編碼是"E5 48"它第二個字節的48正好是ASCII碼中'H'的位置,也就是說,當word是"錒"的第二個字節,並且處理到
if (isLetterOrNumber(word))
會返回true,這個48就會按照英文來處理,放到拼音字符串中。
但是問題來了:既然"錒"的第二個字節是48,而48也在ASCII中,那麼怎麼才能區分出我想要的這個48是"錒"的第二字節,而不是'H'ASCII字符?
PS:我感覺我的markdown語法好像沒有錯,為什麼代碼沒有高亮
邏輯改一下:
if (isChinese(word))
{
chinese = word;
ifs.read((char*)&word, 1); //既然是漢字,就得讀兩次組成一個漢字。
chinese += word;
現在肯定是漢字,無需判斷是否等於2
}
else if (isLetterOrNumber(word)) // 排除漢字後才處理字符和數字
// 放入pinyin字符串
pinyin += word;