Я создал простую программу с использованием регулярных выражений для токенизации файла. Для контента, отличного от Юникода, он работает нормально. Для контента на основе Unicode я сделал версию wregex, но эта версия создает вывод мусора!
Я пытаюсь вывести Unicode-символы или строки на экране консоли, вместо этого я сохранил их в map<wstring,int>
и файл типа wostream, чтобы значения были целыми и правильными.
После запуска приложения файл, содержащий извлеченные токены, содержит просто мусор !!!
Что не так с этой программой и как я могу это исправить?
#include "stdafx.h"
#include <iostream>
#include <regex>
#include <fstream>
#include <string>
#include <map>
using namespace std;
int main()
{
string path="";
map<wstring, int> container;
wifstream file("ftest.txt");
wregex reg(_T("\\w+"));
wstring s=_T("");
while (file.good())
{
file>>s;
for ( wsregex_iterator it (s.begin(), s.end(), reg),it_end; it != it_end; ++it)
{
container[(wstring)(*it)[0]]++ ;
}
}
cout <<"\nDone..."<< endl;
wofstream output("list.txt",ios::app);
for (auto item : container)
{
//cout<<item.first<<" : "<<item.second<<endl;
output<<item.first<<" : "<<item.second<<endl;
}
system("pause");
return 0;
}
Это содержание ftest.txt
:
بسم الله الرحمن الرحیم
واشنگتن پست طی گزارشی اعلام کرد کنگره آمریکا برخلاف رویه سابق، ارسال مصوبه سالانه خود در زمینه تحریم های ایران به کاخ سفید را به تاخیر انداخت و به نظر می رسد انتخاب حسن روحانی به عنوان رئیس جمهوری جدید ایران علت این امر بوده است.
0 0 0 نظر
[-] اندازه متن [+]به دنبال انتخاب حسن روحانی به عنوان رئیس جمهوری جدید ایران، کنگره آمریکا بر اساس برخی ملاحظات ارسال مصوبه سالانه خود در زمینه تحریم های ایران به کاخ سفید را به تاخیر انداخت.
И это вывод мусора внутри list.txt
0 : 3
1 : 1
14 : 1
16 : 1
26 : 1
27 : 1
5 : 2
50 : 1
6 : 1
7 : 1
ط : 475
طھ : 12
طھط : 20
طھطµظ : 1
طھظ : 10
طھغ : 2
ط² : 6
ط²ط : 6
ط²ظ : 6
ط³ : 5
ط³ط : 12
ط³طھ : 8
ط³طھط : 4
ط³طھظ : 2
ط³ظ : 10
ط³غ : 1
طµ : 1
طµط : 1
طµظ : 6
ط¹ط : 1
ط¹ظ : 8
ظ : 291
ع : 54
غ : 95
ï : 1
это ссылка на сайт Решил мою проблему. 🙂 для портативного решения проверьте это ссылка на сайт из.
И это последний код, который работает без нареканий :):
#include "stdafx.h"#include <iostream>
#include <regex>
#include <fstream>
#include <string>
#include <map>
#include <fcntl.h> // for _wfopen_s
#include <io.h> //for _setmodeusing namespace std;
int main()
{
string path = "";
map<wstring, int> container;
FILE* fp;
_wfopen_s (&fp, L"ftest.txt", L"r");
_setmode (_fileno (fp), _O_U8TEXT);
wifstream file(fp);
wregex reg(L"\\w+");
wstring s = L"";
while (file.good())
{
getline(file,s);
for ( wsregex_iterator it (s.begin(), s.end(), reg), it_end ; it != it_end ; ++it)
{
container[(wstring)(*it)[0]]++ ;
}
}
cout <<"\nDone..."<< endl;
fclose(fp);
_wfopen_s (&fp, L"list.txt", L"w");
_setmode (_fileno (fp), _O_U8TEXT);
wofstream output(fp);
for (auto item : container)
{
wcout<<item.first <<" : "<<item.second <<endl;
//write output to list.txt
output<<item.first <<" : "<<item.second <<endl;
}
fclose(fp);
system("pause");
return 0;
}
Вам необходимо преобразовать кодировку UTF8 файла в кодировку UTF16, которая std::wregex
использует.
С C ++ 11 вы можете сделать это с помощью std::codecvt_utf8_utf16
:
std::wifstream file("ftest.txt");
file.imbue(std::locale(file.getloc(), new std::codecvt_utf8_utf16<wchar_t>());
// "file" will now read UTF8 and output UTF16.
Pre C ++ 11 вы можете использовать boost::locale
преобразовать:
например
auto w_s = boost::locale::utf_to_utf<char>(s);