Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кодировки, кодировки...
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Общие вопросы
Rocky
Всем привет!

Подскажите плиз с таким моментом. Беру текстовый файл, открываю, прогоняю его через QTextStream с заданной кодировкой, сохраняю... Все ок. Если 2-й раз сделать тоже самое - вместо русских букв кракозябры... Это нормально? ) Просто как-то непонятно... Помогите разобраться плиз )

Т.е. изначально у файла win1251. Прогнал сохранил в utf-8. На этом моменте все ок.. Потом опять его беру и прогоняю в utf-8 - вместо русских комментов - чушь... ( Ощущение что это как-то связано с юникодом...
Вот функция:
void CFileDecoder::DecodeFile(const QString& sSourceFile, const QString& sWantedCodec) 
{
    QFile oSourceFile(sSourceFile);
    if (!oSourceFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        //...
        return;
    }
    
    QTextStream oInStream(&oSourceFile);
    const QString sCurCodec = oInStream.codec()->name();
    if (!sCurCodec.compare(sWantedCodec, Qt::CaseInsensitive)) return;

    const QString sTargetFile = ...;
    QFile oTargetFile(sTargetFile);
    if (!oTargetFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
    {
        //...
        return;
    }
    
    QTextStream oOutStream(&oTargetFile);
    oOutStream.setCodec(QTextCodec::codecForName(sWantedCodec.toStdString().c_str()));
    oOutStream << oInStream.readAll();


Вот в этом месте я так поинмаю что name() возвращает не кодировку файла, а кодировку которую я выставил для всего приложения (вызовом статической функции)
QTextStream oInStream(&oSourceFile);
const QString sCurCodec = oInStream.codec()->name();

так ведь?
kwisp
Цитата(Rocky @ 26.2.2010, 18:57) *
Вот в этом месте я так поинмаю что name() возвращает не кодировку файла, а кодировку которую я выставил для всего приложения (вызовом статической функции)


по-моему да.


а что ты собственно хочешь сделать?

Цитата(Rocky @ 26.2.2010, 18:57) *
sWantedCodec.toStdString().c_str()

это минимум можно заменить
на
sWantedCodec.toAscii()
или
sWantedCodec.toLatin1()
Rocky
Цитата(kwisp @ 26.2.2010, 19:11) *
sWantedCodec.toStdString().c_str()

это минимум можно заменить
на
sWantedCodec.toAscii()
или
sWantedCodec.toLatin1()

Исправил, спасибо)

Я хочу сделать бесплатный =) перекодировщик файлов. Уже думал что написал, но обнаружил вот такую вещь. Повторюсь: есть файл с какой-то кодировкой (я так думаю что неважно какой). Я хочу его какбы пересохранить с заданной кодировкой. Функция перекодирования выше. Получается, что один раз она срабатывает нормально.. Т.е. на выходе я получаю совершенно нормальный файл с заданной кодировкой. А на 2-й такой "прогон" (того же самого файла) я получаю
Чтобы начать перекодированиР

вместо русских букв (

Вот интерфейсик такой получился:
BRE
Цитата(Rocky @ 26.2.2010, 18:57) *
Т.е. изначально у файла win1251. Прогнал сохранил в utf-8. На этом моменте все ок.. Потом опять его беру и прогоняю в utf-8 - вместо русских комментов - чушь... ( Ощущение что это как-то связано с юникодом...

Есть файл in.txt в кодировке win1251. Ты его конвертируешь в UTF-8 и сохраняешь в файл out.txt.
После этого ты берешь файл out.txt и пытаешься его еще раз конвертировать из win1251 в UTF-8?
Rocky
Сорри, в конце недели туго с речью)

Есть файл in.txt в кодировке win1251. Я его конвертирую в utf-8 и сохраняю в out.txt. Потом in.txt удаляю, out.txt копирую с новым именем (in.txt), потом out.txt удаляю - т.е. как бы меняю имя файла.
    //удаляем sSourceFile
    if (!QFile::remove(sSourceFile))
    {
        QMessageBox::critical(NULL, m_roMessages[eCaption], m_roMessages[eErrorSourceFileNotDeleted].arg(sSourceFile));
        return;
    }

    //копируем sTargetFile в sSourceFile
    if (!QFile::copy(sTargetFile, sSourceFile))
    {
        QMessageBox::critical(NULL, m_roMessages[eCaption], m_roMessages[eErrorSourceFileNotReplaced].arg(sSourceFile));
        return;
    }

    //удаляем sTargetFile
    if (!QFile::remove(sTargetFile))
    {
        QMessageBox::critical(NULL, m_roMessages[eCaption], m_roMessages[eErrorTargetFileNotDeleted].arg(sSourceFile));
        return;
    }


В итоге новый in.txt в кодировке utf-8.

Затем беру этот новый in.txt и снова его конвертирую в туже utf-8.... Он ведь не должен меняться если он уже в этой кодировке? Или нет? или я туплю (
BRE
Цитата(Rocky @ 26.2.2010, 19:52) *
Он ведь не должен- меняться если он уже в этой кодировке? Или нет? или я туплю (

Как-же не должен, именно должен меняться.
Если ты ошибешься с исходной кодировкой, ты всегда будешь видеть кашу.
А сейчас ты именно ошибаешься, файл в кодировке UTF-8 а ты его читаешь как win1251.
Litkevich Yuriy
Цитата(Rocky @ 26.2.2010, 22:28) *
Я хочу сделать бесплатный =) перекодировщик файлов.
дак ведь есть уже:
%QTDIR%\examples\tools\codecs
можешь на его основе сделать, заодно и посмотришь как это делается.
Rocky
Т.е. нужно сначала определить исходную кодировку,затем написать так
 QTextStream oInStream(&oSourceFile);
oInStream.setCodec(....);

Т.е. установить "потоку исходного файла" нужную кодировку и затем уже его считывать и перекодировать в заданной, так? А я почему-то решил что когда делаеш так QTextStream oInStream(&oSourceFile); - oInStream уже в нужной кодировке (в кодировке файла oSourceFile)... Значит пошел разбираться как определять исходную кодировку... Где-то тут вроде уже речь шла про это, остановились вроде как на notepad++. Вобщем, поищу его исходники. Наверное так.

UPD
Цитата(Litkevich Yuriy @ 26.2.2010, 20:05) *
дак ведь есть уже:
%QTDIR%\examples\tools\codecs
можешь на его основе сделать, заодно и посмотришь как это делается.

О, спасибо )

UPD
оказывается %QTDIR%\examples\tools\codecs не позволяет определить автоматически кодировку (
SABROG
Цитата(Rocky @ 26.2.2010, 20:21) *
не позволяет определить автоматически кодировку


Qt умеет определять только UTF16/32 по BOM'у. Так что на него не полагайся. Твоя задача сводится к реализации своего варианта программы "Штирлиц", но даже она ошибается. Поэтому проси пользователя, чтобы жестко задавал исходную и желаемую кодировки, если автоматически определить не удалось. Думаю в интернете должны быть статьи как по частотному анализу букв определить кодировку файла. В разных языках частота встречаемости тоже разная Может быть даже готовые библиотеки есть какие-нибудь.

Простой алгоритм заключает в том, чтобы последовательно предполагать кодировки файлов и пытаться конвертировать другую, затем подсчитывать встречаемость букв. Но этот алгоритм будет работать только на более менее больших файлах, где русский и английский текст не миксуются 50/50.
Rocky
Мдя... а я думал за пару часиков напишу все ) Видимо придется повозиться, если запал не пройдет )
SABROG
Наткнулся на такую библиотеку определения кодировки. Написана на Си, алгоритм содран с детектора Мозиллы, лицензия LGPL.
Rocky
ок, попробуем разобраться) спасибо
Litkevich Yuriy
Rocky, посмотри ещё программу Notepad++, она определяет кодировку самостоятельно (иногда ошибается, когда всё на аглицком написано)
kwisp
смотри еще
enca enconv по ссылке сообщение на этом форуме
и
iconv
это простенькие утилиты под линукс.
я ими пользуюсь:)

П.С.
По-моему, прога твоя будет полезна чисто в образовательных целях.
Практически уже эта проблема решена.
Но ты запал не теряй. :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.