Russian Qt Forum
Апрель 19, 2024, 21:55 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: [РЕШЕНО] QSettings - ini - русские группы и ключи - проблема с кодировками  (Прочитано 31182 раз)
NoIdea
Гость
« : Декабрь 08, 2010, 05:26 »

Есть ini-файл (QSettings) в кодировке Windows-1251 и в нём встречаются русские группы и ключи.
Задача считать его под любой платформой. Щаз реализованно под виндой и то не без проблем.

К примеру, есть такой ini:
Код:
[group]
group=Группа
value=Значение

[Группа]
value=данные
Значение=Ещё данные
Тест=тест данные
Считаем из него сначало название группы и название ключа, а затем по ним данные - максимально приближенная ситуация.

Пример кода считывающего из него значения:
Код:
#include <QtGui/QApplication>
#include <QTextCodec>
#include <QSettings>
#include <QDebug>

int main(int argc, char *argv[])  
{
 QApplication a(argc, argv);

 QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
 QTextCodec::setCodecForTr(codec);
 QTextCodec::setCodecForLocale(codec);
 //QTextCodec::setCodecForCStrings(codec);
 // откоментить и работать перестанет, а по дефолту: Latin-1

 QString group,value;
 QSettings *ini=new QSettings(qApp->applicationDirPath()+"/config.ini",QSettings::IniFormat);
 ini->setIniCodec(codec);

 ini->beginGroup("group");
 group = ini->value("group").toString();
 value = ini->value("value").toString();
 qDebug() << QObject::tr("Считанные значения:") << group << value;

 delete ini;
 // без пересоздания QSettings не работает
 ini=new QSettings(qApp->applicationDirPath()+"/config.ini",QSettings::IniFormat);
 ini->setIniCodec(codec);

 qDebug() << QObject::tr("Получаем данные из русской группы:");
 ini->beginGroup(group.toLocal8Bit()); // без toLocal8Bit() не работает
 qDebug() << ini->value("value").toString();
 qDebug() << ini->value(value.toLocal8Bit()).toString();
 ini->endGroup();
 qDebug() << ini->value("Группа/Тест").toString(); // работает

 return 0;
}

Выводит:
Код:
"Считанные значения:" "Группа" "Значение" 
"Получаем данные из русской группы:"
"данные"
"Ещё данные"
"тест данные"

А под *nix никак не хочет работать и не представляю что там за магия с кодировками...
Уж как только не пробовал конвертить этот group - ничего не выходит

Вообще возможностей по работе с ini в QSettings не достаточно, думаю придётся искать другой парсер или написать самому, потому как в ini встречается ключи без имени или ключи с одинаковым названием - мультилайн. Так что если кто знает что приличное - советуйте!

P.S.> на форуме похоже тоже траблы с кодировкой кириллистических знаков в теге code=cpp, code=ini и т.д.
P.P.S.>Прилагаю тестовый проект
« Последнее редактирование: Декабрь 09, 2010, 00:00 от NoIdea » Записан
BRE
Гость
« Ответ #1 : Декабрь 08, 2010, 07:57 »

void QSettings::setIniCodec ( QTextCodec * codec )
void QSettings::setIniCodec ( const char * codecName )
Записан
NoIdea
Гость
« Ответ #2 : Декабрь 08, 2010, 20:48 »

setIniCodec() использую, что видно из примера...

Вот что получается...

Данный код работает под win:

Код:
ini->beginGroup(group.toLocal8Bit());
qDebug() << ini->value(value.toLocal8Bit()).toString();
ini->endGroup();
тут group=="Группа" value=="Значение"

А под *nix работает только:
Код:
qDebug() << ini->value("Группа/Значение").toString();
Т.е. никак не получается так сконвертить строку group,value чтобы она переварилась под nix.

Вот этого я и не понимаю, ведь в обоих случаях строка должна быть в одной и той же кодировке... в чём тут проблема? Грустный

P.S.> В примере первого поста QTextCodec::setCodecForLocale(codec); - не нужно - косяк.
Записан
BRE
Гость
« Ответ #3 : Декабрь 08, 2010, 21:01 »

Вот объясни мне пожалуйста, что по твоему делает этот кусок кода и какие преобразования он выполняет в каких строках твоей программы:
Код
C++ (Qt)
QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(codec);
//QTextCodec::setCodecForCStrings(codec);
// откоментить и работать перестанет, а по дефолту: Latin-1
 

Как только ты ответишь на этот вопрос, у тебя отпадет желание включать эти строки в свои программы, навсегда.

[offtop] Откуда пошла эта мода? [/offtop]
Записан
BRE
Гость
« Ответ #4 : Декабрь 08, 2010, 21:38 »

Код
C++ (Qt)
#include <QtGui/QApplication>
#include <QTextCodec>
#include <QSettings>
#include <QDebug>
 
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
 
QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
 
QString group, value;
QSettings ini( qApp->applicationDirPath()+"/config.ini",QSettings::IniFormat );
ini.setIniCodec( codec );
 
ini.beginGroup("group");
group = ini.value("group").toString();
value = ini.value("value").toString();
ini.endGroup();
qDebug() << group << value;
 
ini.beginGroup( codec->fromUnicode( group ) );
qDebug() << ini.value("value").toString();
qDebug() << ini.value( codec->fromUnicode( value ) ).toString();
ini.endGroup();
qDebug() << ini.value("Группа/Тест").toString();
 
return 0;
}
 
Записан
NoIdea
Гость
« Ответ #5 : Декабрь 08, 2010, 22:39 »

Вау! Работает! Спасибо!  Смеющийся

А по поводу:
Вот объясни мне пожалуйста, что по твоему делает этот кусок кода и какие преобразования он выполняет в каких строках твоей программы:
Код
C++ (Qt)
QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(codec);
//QTextCodec::setCodecForCStrings(codec);
 

Как только ты ответишь на этот вопрос, у тебя отпадет желание включать эти строки в свои программы, навсегда.


QTextCodec::setCodecForTr(codec);
Устанавливает кодек для tr() исходники в Windows-1251 и language-файлы скорее всего тоже будут... или это не верное решение для портируемого софта? По дефолту там Latin-1 тоже ведь не гуд...

QTextCodec::setCodecForLocale(codec);
Ну менять локаль это явно лишнее это я уже осознал Улыбающийся

QTextCodec::setCodecForCStrings(codec);
устанавливает кодек для строк-переменных, т.е. если они в cp1251 изначально то их не надо конвертить перед вывоводом на экран, но обычно им всё равно требуется tr() так что тоже излишне.

[offtop] Откуда мода? Как знать... Мне приятель посоветовал, мол всё будет в одной кодировке... Улыбающийся [/offtop]
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #6 : Август 28, 2013, 15:51 »

Код
C++ (Qt)
qDebug() << ini.value("Группа/Тест").toString();
 
Оно разве работает? Как заставить QSettings поддерживать русские ключи? со значениями все в порядке.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #7 : Август 28, 2013, 18:14 »

использовать правильный кодек. выше ж все написано.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #8 : Август 29, 2013, 08:27 »

использовать правильный кодек. выше ж все написано.
Я запустил пример из этой ветки(Автор: BRE ). Только файл config.ini превратился в это (записи в настройки не было)
Код:
[group]
group=Группа
value=Значение

[%C3%F0%F3%EF%EF%E0]
value=данные
%C7%ED%E0%F7%E5%ED%E8%E5=Ещё данные
%D2%E5%F1%F2=тест данные

[General]
%D1%ED%E5%E3=123
Программа то работает, но вот в самом файле ключи нечитаемы для человека.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #9 : Август 29, 2013, 21:26 »

Да это косяк трльтеховцев и исправлять они его не намерены, им кроме англицкого языка ничего не надо.
Этот ты ещё пробелы в именах секций не совал, они сразу в процентную кодировку преобразуются не понятно с какого перепугу.
Плюс обратные слеши в значениях ключей QSettings не понимает - тоже школьный курс программирования.
Записан

Юра.
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #10 : Август 30, 2013, 08:48 »

А есть альтернатива QSettings ? Чтобы поддерживал русский язык, хранился в памяти, сохранял при деструкторе или вызове метода Save().

p.s. сам наверно напишу когда время появиться.
« Последнее редактирование: Август 30, 2013, 08:49 от deMax » Записан
Bepec
Гость
« Ответ #11 : Август 30, 2013, 09:10 »

Как показывает моя практика - гораздо лучше использовать латиницу в таких делах.
Проще, быстрее, кроссплатформенно, возможность отредактировать в любом редакторе не думая о кодировках Улыбающийся

PS не гонитесь слишком за "человеческим редактированием". При увеличении количества настроек до 30 - проще написать конфигуратор, чем мучать пользователя.
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #12 : Август 30, 2013, 14:19 »

Как показывает моя практика - гораздо лучше использовать латиницу в таких делах.
Во первых мы Русские люди, программа для Русских. У меня в ключах в группах встречаются имена объектов(есть объекты на Русском), пользователь вряд ли полезет в этот файл
Записан
Bepec
Гость
« Ответ #13 : Август 30, 2013, 14:39 »

1) Я высказался по поводу BOM.

2) Ну я не знаю что у вас там и как с русским. По идее всё должно работать, главное что бы вы с кодировками не путались сами.

PS если у вас пользователю туда не лезут - плюньте на человеко читаемый формат Веселый
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #14 : Август 30, 2013, 18:47 »

>>Чтобы ..., хранился в памяти, ...
А нужен ли тебе QSettings в таком случае?
Записан

Юра.
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.164 секунд. Запросов: 22.