2013-05-24 8 views
9

C'è un problema nell'uso di QString::arg() quando una stringa contiene una cifra subito dopo un segnaposto. Non è chiaro dalla descrizione della funzione QString::arg() cosa succederebbe in caso di tale sostituzione:Risoluzione QTs QString arg() ambiguità

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

Sarà questo risultato nella "String for replacement blah234" o "String for replacement blah34"?

Ho cercato nel codice sorgente del QT di rispondere a questa domanda. Sembra che l'algoritmo che cerca i marcatori di luogo sia 'avido' e prenderebbe entrambe le cifre nell'esempio sopra.

Qui è la sorgente della funzione del QT che viene utilizzato all'interno del 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; 
} 

Esiste un modo migliore per risolvere tale ambiguità di usare sempre un posto a 2 cifre marcatori?

+3

Questo è un eccellente osservazione, non ho mai pensato a questo. L'unica cosa che penserei di fare è 'QString (" String for replacement% 1% 2 "). Arg (" blah "). Arg (234);', ma è piuttosto brutto. –

risposta

2

Dal momento che è possibile utilizzare solo %1-%99 come marcatori e si può saltare i numeri dei marker si può scrivere:

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

alla stringa di uscita per la sostituzione blah234

+1

E commenta tutto perché non sarà sicuramente intuitivo per la prossima persona che guarda il codice (o te stesso tra 3 anni). Almeno funziona però. – iamtheddrman

+0

Grazie.Sembra che sia l'unica buona soluzione. –

3

Qt aiutare gli stati Arg (const QString & a, int fieldWidth = 0, QChar fillchar = QLatin1Char (''))

restituisce una copia di questa stringa con il contrassegno posto numero più basso sostituito con una stringa a, cioè% 1,% 2, ...,% 99.

...

Luogo numeri marcatori deve essere compreso tra 1 a 99.

Pertanto, quello che stai vedendo è, per definizione, corretta; i primi due numeri saranno sostituiti. Se hai intenzione "Stringa per blah234 sostituzione", allora si potrebbe definire la stringa come: -

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

Non sto dicendo che qualcosa non è corretto. Sto dicendo che una cifra dopo un segnaposto crea qualche ambiguità. C'è spazio extra tra gli indicatori di posizione nella soluzione. Nel caso ci sia uno spazio, non esiste un problema di questo tipo. –

0

ho lo stesso problema, ma le risposte di ordine non sembra un buon modo per me.

Ho risolto l'ambiguità in questo modo.

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

La stringa sarà:

ConcatenatedNumbers06623