2013-05-24 18 views
9

Wystąpił problem przy użyciu QString::arg(), gdy ciąg zawiera cyfrę zaraz za znacznikiem miejsca. To nie wynika z QString::arg() opisie funkcji, co stałoby się w przypadku takiej wymiany:Rozwiązywanie problemu QString QTtring() niejednoznaczności

QString("String for replacement %1234").arg("blah"); 

Spowoduje to "String for replacement blah234" lub "String for replacement blah34"?

Sprawdziłem kod źródłowy QT, aby odpowiedzieć na to pytanie. Wydaje się, że algorytm, który szuka markerów miejsca, jest "chciwy" i w powyższym przykładzie potrzebowałby obu cyfr.

Oto źródło funkcji QT, który jest używany wewnątrz QString::arg() (Qt 4.8.4):

static ArgEscapeData findArgEscapes(const QString &s) 
{ 
const QChar *uc_begin = s.unicode(); 
const QChar *uc_end = uc_begin + s.length(); 

ArgEscapeData d; 

d.min_escape = INT_MAX; 
d.occurrences = 0; 
d.escape_len = 0; 
d.locale_occurrences = 0; 

const QChar *c = uc_begin; 
while (c != uc_end) { 
    while (c != uc_end && c->unicode() != '%') 
     ++c; 

    if (c == uc_end) 
     break; 
    const QChar *escape_start = c; 
    if (++c == uc_end) 
     break; 

    bool locale_arg = false; 
    if (c->unicode() == 'L') { 
     locale_arg = true; 
     if (++c == uc_end) 
      break; 
    } 

    if (c->digitValue() == -1) 
     continue; 

    int escape = c->digitValue(); 
    ++c; 

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

    if (escape > d.min_escape) 
     continue; 

    if (escape < d.min_escape) { 
     d.min_escape = escape; 
     d.occurrences = 0; 
     d.escape_len = 0; 
     d.locale_occurrences = 0; 
    } 

    ++d.occurrences; 
    if (locale_arg) 
     ++d.locale_occurrences; 
    d.escape_len += c - escape_start; 
} 
return d; 
} 

Czy istnieje lepszy sposób na rozwiązanie takiej dwuznaczności niż zawsze przy użyciu 2-cyfrową miejsce markery?

+3

To doskonałą obserwację, nigdy nie myślałem o tym. Jedyne, co mógłbym zrobić, to 'QString (" String for replacement% 1% 2 "). Arg (" blah "). Arg (234);', ale to dość brzydkie. –

Odpowiedz

2

Ponieważ można używać tylko %1 do %99 jako markery i można pominąć liczby markerów można napisać:

QString("String for replacement %10234").arg("blah"); 

String wyjściowego dla wymiany blah234

+1

I skomentuj to, ponieważ z pewnością nie będzie to intuicyjne dla następnej osoby przeglądającej kod (lub dla ciebie 3 lata od teraz). Przynajmniej działa. – iamtheddrman

+0

Dzięki.Wygląda na to, że to jedyne dobre rozwiązanie. –

3

Qt stany pomoc dla Arg (const QString & a, int szerokości pola = 0, QChar fillChar = QLatin1Char (''))

Zwraca kopię tego napisu z najniższym numerze miejscu znacznik zastąpiono przez ciąg a, tj.% 1,% 2, ...,% 99.

...

Place numery marker musi mieścić się w przedziale od 1 do 99.

Dlatego, co widzisz jest, z definicji, prawidłowe; pierwsze dwie liczby zostaną zastąpione. Jeśli chce „ciąg do zastąpienia blah234”, a następnie można zdefiniować jako ciąg: -

QString("String for replacement %1%2").arg("blah").arg(234); 
+3

Nie mówię, że coś jest nie tak. Mówię, że cyfra po znaczniku miejsca tworzy pewną niejednoznaczność. W wyznaczonym miejscu znajduje się dodatkowa przestrzeń między znacznikami miejsc. Jeśli jest miejsce, nie ma takiego problemu. –

0

mam ten sam problem, ale odpowiedzi nie wygląda zamów dobry sposób dla mnie.

Rozwiązałem tę dwuznaczność w ten sposób.

QString myString= QString("ConcatenatedNumbers%0123").arg(66,3,10, QChar('0')); 

Ciąg będą:

ConcatenatedNumbers06623 
Powiązane problemy