2017-02-16 1 views
0

J'ai un QString et je voudrais générer une nouvelle chaîne avec tous les caractères séparés. Une façon serait d'itérer manuellement sur la chaîne et d'insérer le séparateur après chaque caractère, sauf le dernier.Comment diviser QString en caractères individuels et en créer un nouveau?

Existe-t-il une meilleure méthode ou au moins une méthode plus directe sans avoir à implémenter la boucle? Par exemple, pour utiliser directement comme paramètre de fonction. Si possible, n'utilisez que Qt.

const QString s("Hello world!"); 
const QString r(some_separating_function(s)); 
qDebug() << r; 

Le résultat attendu serait

"H-e-l-l-o- -w-o-r-l-d-!" 

EDIT: Je suis auto-y répondre puisque je ne l'ai pas trouvé une meilleure solution en SO et je trouve utile. Si quelqu'un a une meilleure solution, je l'apprécierai.

Répondre

1

Voici une façon qui n'alloue pas temporaires:

// https://github.com/KubaO/stackoverflown/tree/master/questions/string-sep-42276882 
#include <QtCore> 

QString separate1(const QString & string, const QString & separator) { 
    QString result; 
    result.reserve(string.size() * (1 + separator.size())); 
    for (auto ch : string) { 
     result.append(ch); 
     result.append(separator); 
    } 
    result.chop(separator.size()); 
    return result; 
} 

Hélas, copy-on-write de QString a encore des frais généraux, de sorte que le traitement des données directement sera encore plus rapide :

QString separate(const QString & string, const QString & separator) { 
    QString result{string.size() + (string.size()-1) * separator.size(), 
        Qt::Uninitialized}; 
    auto const end = result.data() + result.size(); 
    int s{}; 
    for (auto p = result.data(); p < end;) { 
    *p++ = string.at(s++); 
     if (Q_LIKELY(p < end)) 
     for (auto const ch : separator) 
      *p++ = ch; 
    } 
    return result; 
} 

Et pour le vérifier:

int main() { 
    auto const separator = QStringLiteral("-"); 
    auto const source = QStringLiteral("Hello world!"); 
    auto const compare = QStringLiteral("H-e-l-l-o- -w-o-r-l-d-!"); 
    Q_ASSERT(separate1(source, separator) == compare); 
    Q_ASSERT(separate(source, separator) == compare); 
} 
2

La meilleure façon que je l'ai trouvé à ce jour est d'utiliser la méthode QString::split avec une chaîne vide comme séparateur, ce qui arrive à créer un QList de caractères individuels (en fait, un QList avec des chaînes 1 caractères).

const QString s("Hello world!"); 
const QString r(s.split("", QString::SkipEmptyParts).join('-'));