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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QString().arg() bug ?  (Прочитано 12576 раз)
burunduk
Гость
« : Март 30, 2006, 11:17 »

QString s = QString("%10%2").arg("A").arg("B");

результат выражения: BA

Я вообще-то ожидал выражения A0B.


Qt 4.1.0 open-source
Записан
Asaphus_Expansus
Гость
« Ответ #1 : Март 30, 2006, 11:37 »

Это не баг, это фича.

Теперь arg не ограничивается %9, как я понимаю, поэтому он парсит %10 как 10. А заменяет двойку, B - десятку.

Варианты решения:
QString("%1 \b0%2").arg("A").arg("B")
QString("%1%2").arg("A0").arg("B")
QString("%1%2%3").arg("A").arg("0").arg("B")
Записан
burunduk
Гость
« Ответ #2 : Март 30, 2006, 11:44 »

В документации написано:

QString QString::arg ( const QString & a, int fieldWidth = 0, const QChar & fillChar = QLatin1Char( ' ' ) ) const

This function returns a copy of this string where a replaces the lowest numbered occurrence of %1, %2, ..., %9.
Записан
Asaphus_Expansus
Гость
« Ответ #3 : Март 30, 2006, 11:48 »

Ну дока всегда немножко более старая чем положено, я еще со времен Qt 1.31 к этому привык Улыбающийся

В коде же мы видим

        int escape = c->digitValue();
        if (escape != -1) {
            if (c + 1 != uc_end && (c + 1)->digitValue() != -1) {
                escape = (10 * escape) + (c + 1)->digitValue();
                ++c;
            }
        }

что даже комментировать не нужно, я полагаю Улыбающийся
Записан
burunduk
Гость
« Ответ #4 : Март 30, 2006, 12:03 »

ясно, спасибо Улыбающийся
Записан
Dendy
Гость
« Ответ #5 : Март 30, 2006, 12:23 »

Дока с Qt 4.1.1

This function returns a copy of this string where a replaces the lowest numbered occurrence of %1, %2, ..., %99.

arg() будет заменять первую младшую цифру что найдёт. ИМХО все три решения не катят.

1. \b вставляет символ, которьІй в машинном коде будет присутствовать в строке.
2. не катит, если "A" или "B" хранятся в переменньІх.
3. тож коряво, "0" не должен вставляться, хотя...

ИМХО, вот наверное более "правильньІй" способ:

Код:
QStrings = QString( "%1" ).arg( stra + "0" + strb );
Записан
Asaphus_Expansus
Гость
« Ответ #6 : Март 30, 2006, 12:46 »

Цитировать

все три решения не катят


Все три решения работают для вывода на экран в рамках поставленой задачи - на экран выводится "A0B".

Цитировать

QString s = QString( "%1" ).arg( stra + "0" + strb );


"Бессмысленно и беспощадно".

По одной простой причине: основное назначение функции arg(), это вывод аргументов в строки ПОДЛЕЖАЩИЕ ЛОКАЛИЗАЦИИ, для того, чтобы правильно сформировать сообщения, сообразно требованиям языка.

Например: в английском варианте вы можете указать строку
"Error %1 found in line %2", а в русском "В строке %2 обнаружена ошибка %1".
Код будет работать правильно без перекомпиляции.

Ваше решение (в котором вообще непонятно зачем нужна функция arg()) напрочь убивает это достоинство, поскольку порядок следования аргументов и их склейка явно прошиты в код, что совершенно не comme il faut.
Записан
Dendy
Гость
« Ответ #7 : Март 30, 2006, 13:19 »

Кхмммм..... Неужели вьІ думаете, что задававшему вопрос решение нужно только для того, чтобьІ вьІводить "A0B"? В таком случае

Код:
QString s( "A0B" );


тоже решение задачи.

Локализация - одна из фич, расширяемая данной функцией, но совершенно не основная. Главное - форматирование, то-есть упорядоченная строка из нескольких вставок произвольного типа. Так что если в данной задаче главное - порядок, то соединение строк с нулём посередине можно делать и простой конкатенацией. А свой пример я предоставил только, чтобьІ показать универсальность: результирующая строка вставляется в шаблон, и конечно же глупо бьІло бьІ оставить его как: QString( "%1" ). Ето не нужно обьяснять.
Записан
Asaphus_Expansus
Гость
« Ответ #8 : Март 30, 2006, 13:32 »

Цитировать

Локализация - одна из фич, расширяемая данной функцией, но совершенно не основная. Главное - форматирование, то-есть упорядоченная строка из нескольких вставок произвольного типа.


Для простого форматирования изначально был sprintf() а сейчас рекомендуется QTextOStream.

arg() изначально планировался под локализацию и именно это и есть его целевое назначение. Именно для этого кроме простых %1 %2 etc реализованы еще и %L1, %L2 ...

Цитировать

For translations, especially if the strings contains more than one escape sequence, you should consider using the arg() function instead. This allows the order of the replacements to be controlled by the translator.
Записан
Dendy
Гость
« Ответ #9 : Март 30, 2006, 15:32 »

Согласен, без данного метода локализация в стиле Qt потеряла бьІ очень много. Но есть ещё множество случаев для простого форматирования, например при обращении к файловой системе.

Пожалуйста, обьясните как из вьІражения:

Код:
QString( "%1 \b0%2" ).arg( "A" ).arg( "B" );


должна получиться строка "A0B". Проверил на практике: вместо \b вставляется какой-то спецвимвол.
Записан
Asaphus_Expansus
Гость
« Ответ #10 : Март 30, 2006, 15:39 »

Цитировать

Пожалуйста, обьясните как из вьІражения:
Цитировать

Код:
QString( "%1 \b0%2" ).arg( "A" ).arg( "B" );

должна получиться строка "A0B". Проверил на практике: вместо \b вставляется какой-то спецвимвол.


Вы не знаете что такое '\b' в строках C/C++ или не знаете как этот символ отрабатывается при выводе на консольный экран (или, исторически, на принтер) ?

Или Вы пытаетесь расказать, что байтовый массив будет отличен от "A0B"? Ну так это всем очевидно.
Записан
Dendy
Гость
« Ответ #11 : Март 30, 2006, 16:00 »

Етим спец-символом пользоваться не приходилось. Пожалуйста, ответьте на вопрос. Как должна получиться строка "A0B" из такого вьІражения?
Записан
Asaphus_Expansus
Гость
« Ответ #12 : Март 30, 2006, 16:15 »

Ок, извините за некоторый сарказм, я не предполагал, что Вы, выказывающий приличное знание Qt по многим вопросам действительно не знаете что такое '\b'.

Это специальный символ, который препроцессором компилятора заменяется на байт с десятичным значением 8 (0x08), который согласно таблице Ascii интерпретируется стандартными устройствами ввода-вывода как Backspace, и требует перемещения позиции вывода следующего символа на один символ влево (back space). Таким образом строка "A \b0B" при выводе на консольный экран или принтер будет отображаться как строка "A0B".

Таким образом, если задача состоит в получении нужной строки на символьно-ориентированом устройстве, решение об использовании формата "%1 \b0%2" может оказаться вполне оправданным. Естественно, нужно помнить о некоторых ограничениях, накладываемых данным решением.
Записан
L.Marvell
Гость
« Ответ #13 : Март 30, 2006, 16:34 »

А разве без \b нельзя обойтись? Например так: QString( "%1'0'%2" ).arg( "A" ).arg( "B" );
Записан
Asaphus_Expansus
Гость
« Ответ #14 : Март 30, 2006, 16:55 »

'\b' появился из необходимости иметь между 1 и 0 "невидимый" не цифровой символ, иначе 1 и 0 будут интерпретированы как число 10.

Ваш пример даст строку А'0'B, поскольку одинарные кавычки внутри двойных, суть обычный символ (с десятичным кодом 39 (0x27)) и он будет выводиться при печати.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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