如何将 QString 拆分成单个字符并创建一个新字符?

How to split QString into individual characters and create a new one?

我有一个 QString,我想生成一个所有字符都分开的新字符串。一种方法是手动遍历字符串并在除最后一个字符之外的每个字符之后插入分隔符。

是否有更好的方法或者至少是更直接的方法而无需实现循环?例如,为了直接用作函数参数。如果可能,只使用 Qt。

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

预期输出为

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

编辑:我正在自我回答,因为我没有在 SO 中找到更好的解决方案,而且我发现它很有用。如果有人有更好的解决方案,我将不胜感激。

到目前为止,我发现的最佳方法是使用 QString::split 方法,并以空字符串作为分隔符,这恰好创建了单个字符的 QList(实际上,QList 有 1 个字符 QStrings).

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

这是一种不分配任何临时对象的方法:

// https://github.com/KubaO/Whosebugn/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;
}

唉,QString的copy-on-write还是有些开销的,直接处理数据会更快:

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;
}

并查看:

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);
}