CString read()
{
CStdioFile f(_T("ds.txt"), CFile::modeRead | CFile::typeText);
CString str;
f.ReadString(str);
return str;
}
//…
pDC ->TextOut(10, 10, read())
//…
ввод\вывод и Unicode
Задача: В ходе работы считываются строки из тесктового-ASCII файла и выводятся в программе (символы в файле - русские).
Решений несколько, например:
1. Считывать в массив char[], конвертировать MultiBiteToWideChar()в wchar_t[] и отправлять в соотв. Функции
2. Не конвертировать и отправлять ASCII версии функций н.п. TextOutA()
Но в MFC программе вызвать ASCII версию функции, что - то не получилось, поэтому решил применить первый способ. Написал пару функций – одна для чтения использует стандартные потоки, вторая CStdioFile, и как-то решил протестить их, выкинув код конвертирования в Unicode и вот, что получилось:
Код:
Естественно ничего хорошего не выведет – строку не конвертировал
Код:
CString read()
{
ifstream file(_T("ds.txt"));
char b[256];
CString str;
file >> b;
str = b;
return str;
}
//…
pDC ->TextOut(10, 10, read())
//…
{
ifstream file(_T("ds.txt"));
char b[256];
CString str;
file >> b;
str = b;
return str;
}
//…
pDC ->TextOut(10, 10, read())
//…
А этот вариант выводит строку правильно, хотя я ее не конвертировал
Вопрос: почему второй вариант правильно работает?
И вообще работа ввода-вывода для Unicode вызывает у меня много вопросов и недоумение, особенно это касается потоков С++, например : почему wifstream считывает по одному байту (MFCишный CStdioFile::ReadString() - тоже) и т.д.
Читаю “The C++ Standart Library” Джосьютиса , главу про интернационализацию, но пока что-то ясности не вижу.
Цитата: MegaMozg
Вопрос: почему второй вариант правильно работает?
Собственно никаких странностей нет. Просто во втором варианте, если я не ошибаюсь, работает перегруженный оператор CString'а, который и преобразует char[] в Unicode.
Цитата: MegaMozg
Но в MFC программе вызвать ASCII версию функции, что - то не получилось, поэтому решил применить первый способ.
А вот здесь поподробней. Почему это?
Код:
CStringA stra = "Александр";
pDC ->TextOutA(10, 10, stra);
pDC ->TextOutA(10, 10, stra);
выдает:
Код:
error C2039: 'TextOutA' : is not a member of 'CDC'
Ну а со "странным поведением" функций - я думаю нужно, просто, перед использованием той или иной функции, читать ее описание в MSDN...
Цитата: MegaMozg
Код:
CStringA stra = "Александр";
pDC ->TextOutA(10, 10, stra);
pDC ->TextOutA(10, 10, stra);
выдает:
Код:
error C2039: 'TextOutA' : is not a member of 'CDC'
Да. Все верно. Так и должно быть. Это я немного затупил. Ведь TextOut так и объявлен в классе - CDC::TextOut. И уже в зависимости директивы раскрывается в TextOutW или TextOutA. Зато вы можете использовать API функции ::TextOutW и ::TextOutA в вашем проекте независимо от выбранной кодировки.
Главная моя проблема, что я все же не понимаю, ЧТО И КАК должны делать потоки C++: wifstream, wofstream, Юникод-версии функций файлового ввода\вывода API и MFC и т.д.
Для хранения символа они используют 2-х байтовый wchar_t, а считывают по одному байту…
А код:
Код:
void write()
{
wofstream file(_T("result.txt"));
wchar_t b[256] = _T("Александр");
file << b;
}
{
wofstream file(_T("result.txt"));
wchar_t b[256] = _T("Александр");
file << b;
}
Код:
void write()
{
CStdioFile f(_T("ds.txt"), CFile::modeWrite | CFile::typeText);
CString str = _T("Александр");
f.WriteString(str);
}
{
CStdioFile f(_T("ds.txt"), CFile::modeWrite | CFile::typeText);
CString str = _T("Александр");
f.WriteString(str);
}
Вообще не работает
для того, чтоб заставить поток читать/писать в нужной нам кодировке, задаем соответствующую локаль, и все работу по перекодированию поток берет на себя.