static QString QString::asprintf(const char *cformat, ...) static QString QString::vasprintf(const char *cformat, va_list ap)是qt 中用于格式化输出到QString中的静态方法。两者区别就是一个传入可变参数,一个传入va_list。 使用案例如下:
QString fun(char* msg,...){
va_list ap;
va_start(ap, msg);
QString buf = QString::vasprintf(msg, ap);
va_end(ap);
return buf;
}
int main()
{
char format[]= "++++%s,%d,%f****";
QString str= fun(format,"fefgew",10,44.3);
qDebug()<<str; //输出"++++fefgew,10,44.300000****"
QString str1= asprintf(format,"fefgew",10,44.3)
qDebug()<<str1; //输出"++++fefgew,10,44.300000****"
return 0;
}
QString QString::asprintf(const char *cformat, ...)
{
va_list ap;
va_start(ap, cformat);
const QString s = vasprintf(cformat, ap);
va_end(ap);
return s;
}
enum LengthMod { lm_none, lm_hh, lm_h, lm_l, lm_ll, lm_L, lm_j, lm_z, lm_t };
static inline bool can_consume(const char * &c, char ch) Q_DECL_NOTHROW
{
if (*c == ch) {
++c;
return true;
}
return false;
}
static LengthMod parse_length_modifier(const char * &c) Q_DECL_NOTHROW
{
switch (*c++) {
case 'h': return can_consume(c, 'h') ? lm_hh : lm_h;
case 'l': return can_consume(c, 'l') ? lm_ll : lm_l;
case 'L': return lm_L;
case 'j': return lm_j;
case 'z':
case 'Z': return lm_z;
case 't': return lm_t;
}
--c; // don't consume *c - it wasn't a flag
return lm_none;
}
QString QString::vasprintf(const char *cformat, va_list ap)
{
if (!cformat || !*cformat) {
// Qt 1.x compat
return fromLatin1("");
}
// Parse cformat
QString result;
const char *c = cformat;
for (;;) {
// Copy non-escape chars to result
const char *cb = c;
while (*c != '\0' && *c != '%')
c++;
append_utf8(result, cb, int(c - cb));
if (*c == '\0')
break;
// Found '%'
const char *escape_start = c;
++c;
if (*c == '\0') {
result.append(QLatin1Char('%')); // a % at the end of the string - treat as non-escape text
break;
}
if (*c == '%') {
result.append(QLatin1Char('%')); // %%
++c;
continue;
}
uint flags = parse_flag_characters(c);
if (*c == '\0') {
result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
break;
}
// Parse field width
int width = -1; // -1 means unspecified
if (qIsDigit(*c)) {
width = parse_field_width(c);
} else if (*c == '*') { // can't parse this in another function, not portably, at least
width = va_arg(ap, int);
if (width < 0)
width = -1; // treat all negative numbers as unspecified
++c;
}
if (*c == '\0') {
result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
break;
}
// Parse precision
int precision = -1; // -1 means unspecified
if (*c == '.') {
++c;
if (qIsDigit(*c)) {
precision = parse_field_width(c);
} else if (*c == '*') { // can't parse this in another function, not portably, at least
precision = va_arg(ap, int);
if (precision < 0)
precision = -1; // treat all negative numbers as unspecified
++c;
}
}
if (*c == '\0') {
result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
break;
}
const LengthMod length_mod = parse_length_modifier(c);
if (*c == '\0') {
result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
break;
}
// Parse the conversion specifier and do the conversion
QString subst;
switch (*c) {
case 'd':
case 'i': {
qint64 i;
switch (length_mod) {
case lm_none: i = va_arg(ap, int); break;
case lm_hh: i = va_arg(ap, int); break;
case lm_h: i = va_arg(ap, int); break;
case lm_l: i = va_arg(ap, long int); break;
case lm_ll: i = va_arg(ap, qint64); break;
case lm_j: i = va_arg(ap, long int); break;
case lm_z: i = va_arg(ap, size_t); break;
case lm_t: i = va_arg(ap, int); break;
default: i = 0; break;
}
subst = QLocaleData::c()->longLongToString(i, precision, 10, width, flags);
++c;
break;
}
case 'o':
case 'u':
case 'x':
case 'X': {
quint64 u;
switch (length_mod) {
case lm_none: u = va_arg(ap, uint); break;
case lm_hh: u = va_arg(ap, uint); break;
case lm_h: u = va_arg(ap, uint); break;
case lm_l: u = va_arg(ap, ulong); break;
case lm_ll: u = va_arg(ap, quint64); break;
case lm_z: u = va_arg(ap, size_t); break;
default: u = 0; break;
}
if (qIsUpper(*c))
flags |= QLocaleData::CapitalEorX;
int base = 10;
switch (qToLower(*c)) {
case 'o':
base = 8; break;
case 'u':
base = 10; break;
case 'x':
base = 16; break;
default: break;
}
subst = QLocaleData::c()->unsLongLongToString(u, precision, base, width, flags);
++c;
break;
}
case 'E':
case 'e':
case 'F':
case 'f':
case 'G':
case 'g':
case 'A':
case 'a': {
double d;
if (length_mod == lm_L)
d = va_arg(ap, long double); // not supported - converted to a double
else
d = va_arg(ap, double);
if (qIsUpper(*c))
flags |= QLocaleData::CapitalEorX;
QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
switch (qToLower(*c)) {
case 'e': form = QLocaleData::DFExponent; break;
case 'a': // not supported - decimal form used instead
case 'f': form = QLocaleData::DFDecimal; break;
case 'g': form = QLocaleData::DFSignificantDigits; break;
default: break;
}
subst = QLocaleData::c()->doubleToString(d, precision, form, width, flags);
++c;
break;
}
case 'c': {
if (length_mod == lm_l)
subst = QChar((ushort) va_arg(ap, int));
else
subst = QLatin1Char((uchar) va_arg(ap, int));
++c;
break;
}
case 's': {
if (length_mod == lm_l) {
const ushort *buff = va_arg(ap, const ushort*);
const ushort *ch = buff;
while (*ch != 0)
++ch;
subst.setUtf16(buff, ch - buff);
} else
subst = QString::fromUtf8(va_arg(ap, const char*));
if (precision != -1)
subst.truncate(precision);
++c;
break;
}
case 'p': {
void *arg = va_arg(ap, void*);
const quint64 i = reinterpret_cast<quintptr>(arg);
flags |= QLocaleData::ShowBase;
subst = QLocaleData::c()->unsLongLongToString(i, precision, 16, width, flags);
++c;
break;
}
case 'n':
switch (length_mod) {
case lm_hh: {
signed char *n = va_arg(ap, signed char*);
*n = result.length();
break;
}
case lm_h: {
short int *n = va_arg(ap, short int*);
*n = result.length();
break;
}
case lm_l: {
long int *n = va_arg(ap, long int*);
*n = result.length();
break;
}
case lm_ll: {
qint64 *n = va_arg(ap, qint64*);
*n = result.length();
break;
}
default: {
int *n = va_arg(ap, int*);
*n = result.length();
break;
}
}
++c;
break;
default: // bad escape, treat as non-escape text
for (const char *cc = escape_start; cc != c; ++cc)
result.append(QLatin1Char(*cc));
continue;
}
if (flags & QLocaleData::LeftAdjusted)
result.append(subst.leftJustified(width));
else
result.append(subst.rightJustified(width));
}
return result;
}
va_list原理及用法_张珂荣的博客-CSDN博客_va_list
man fprintf printf sprintf vfprintf vsprintf_ta是一个搬运工的博客-CSDN博客
C/C++ asprintf正确使用方法,以及和sprintf的比较_再奋斗10年的博客-CSDN博客_asprintf