📄 qstring.cpp
字号:
if ( digit >= 0 && digit <= lastDigit ) { result += *args[argForDigit[digit]]; i += 2; continue; } } result += uc[i++]; } return result;}#ifndef QT_LOCAL_NUMBER_CONVERSIONvoid qt_fix_double(char *str){ struct lconv *lc = localeconv(); const char *thousands_sep = lc->thousands_sep; if (!thousands_sep) thousands_sep = ""; const char *decimal_point = lc->decimal_point; if (!decimal_point || decimal_point[0] == '\0') decimal_point = "."; if (decimal_point[0] != '.' || decimal_point[1] != '\0' || thousands_sep[0] != '\0') { QCString cstr(str); cstr.replace(thousands_sep, ""); cstr.replace(decimal_point, "."); memcpy(str, cstr.data(), cstr.length()+1); }}#elsevoid qt_fix_double(char *) {}#endif/*! Safely builds a formatted string from the format string \a cformat and an arbitrary list of arguments. The format string supports all the escape sequences of printf() in the standard C library. The %s escape sequence expects a utf8() encoded string. The format string \e cformat is expected to be in latin1. If you need a Unicode format string, use arg() instead. For typesafe string building, with full Unicode support, you can use QTextOStream like this: \code QString str; QString s = ...; int x = ...; QTextOStream( &str ) << s << " : " << x; \endcode For \link QObject::tr() translations,\endlink especially if the strings contains more than one escape sequence, you should consider using the arg() function instead. This allows the order of the replacements to be controlled by the translator, and has Unicode support. \sa arg()*/#ifndef QT_NO_SPRINTFQString &QString::sprintf( const char* cformat, ... ){ va_list ap; va_start( ap, cformat ); if ( !cformat || !*cformat ) { // Qt 1.x compat *this = fromLatin1( "" ); return *this; } QString format = fromAscii( cformat ); QRegExp escape( QString::fromLatin1("%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?") ); QString result; uint last = 0; int pos; int len = 0; for (;;) { pos = escape.search( format, last ); len = escape.matchedLength(); // Non-escaped text if ( pos > (int)last ) result += format.mid( last, pos - last ); if ( pos < 0 ) { // The rest if ( last < format.length() ) result += format.mid( last ); break; } last = pos + len + 1; // Escape QString f = format.mid( pos, len ); uint width, decimals; int params = 0; int wpos = f.find('*'); if ( wpos >= 0 ) { params++; width = va_arg( ap, int ); if ( f.find('*', wpos + 1) >= 0 ) { decimals = va_arg( ap, int ); params++; } else { decimals = 0; } } else { decimals = width = 0; } QString replacement; if ( format[pos + len] == 's' || format[pos + len] == 'S' || format[pos + len] == 'c' ) { bool rightjust = ( f.find('-') < 0 ); // %-5s really means left adjust in sprintf if ( wpos < 0 ) { QRegExp num( fromLatin1("[0-9]+") ); int p = num.search( f ); int nlen = num.matchedLength(); int q = f.find( '.' ); if ( q < 0 || (p < q && p >= 0) ) width = f.mid( p, nlen ).toInt(); if ( q >= 0 ) { p = num.search( f, q ); // "decimals" is used to specify string truncation if ( p >= 0 ) decimals = f.mid( p, nlen ).toInt(); } } if ( format[pos + len] == 's' ) { QString s = QString::fromUtf8( va_arg(ap, char*) ); replacement = ( decimals <= 0 ) ? s : s.left( decimals ); } else { int ch = va_arg(ap, int); replacement = QChar((ushort)ch); } if ( replacement.length() < width ) { replacement = rightjust ? replacement.rightJustify(width) : replacement.leftJustify(width); } } else if ( format[pos+len] == '%' ) { replacement = '%'; } else if ( format[pos+len] == 'n' ) { int* n = va_arg(ap, int*); *n = result.length(); } else { char in[64], out[330]; strncpy(in,f.latin1(),63); out[0] = '\0'; char fch = format[pos+len].latin1(); in[f.length()] = fch; switch ( fch ) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { int value = va_arg( ap, int ); switch ( params ) { case 0: ::sprintf( out, in, value ); break; case 1: ::sprintf( out, in, width, value ); break; case 2: ::sprintf( out, in, width, decimals, value ); } } break; case 'e': case 'E': case 'f': case 'g': case 'G': { double value = va_arg( ap, double ); switch ( params ) { case 0: ::sprintf( out, in, value ); break; case 1: ::sprintf( out, in, width, value ); break; case 2: ::sprintf( out, in, width, decimals, value ); } qt_fix_double(out); } break; case 'p': { void* value = va_arg( ap, void * ); switch ( params ) { case 0: ::sprintf( out, in, value ); break; case 1: ::sprintf( out, in, width, value ); break; case 2: ::sprintf( out, in, width, decimals, value ); } } } replacement = fromAscii( out ); } result += replacement; } *this = result; va_end( ap ); return *this;}#endif/*! Fills the string with \a len characters of value \a c, and returns a reference to the string. If \a len is negative (the default), the current string length is used. \code QString str; str.fill( 'g', 5 ); // string == "ggggg" \endcode*/QString& QString::fill( QChar c, int len ){ if ( len < 0 ) len = length(); if ( len == 0 ) { *this = ""; } else { deref(); QChar * nd = QT_ALLOC_QCHAR_VEC( len ); d = new QStringData(nd,len,len); while (len--) *nd++ = c; } return *this;}/*! \fn QString QString::copy() const \obsolete In Qt 2.0 and later, all calls to this function are needless. Just remove them.*//*! \overload Finds the first occurrence of the character \a c, starting at position \a index. If \a index is -1, the search starts at the last character; if -2, at the next to last character and so on. (See findRev() for searching backwards.) If \a cs is TRUE (the default), the search is case sensitive; otherwise the search is case insensitive. Returns the position of \a c or -1 if \a c could not be found.*/int QString::find( QChar c, int index, bool cs ) const{ const uint l = length(); if ( index < 0 ) index += l; if ( (uint)index >= l ) return -1; register const QChar *uc = unicode()+index; const QChar *end = unicode() + l; if ( cs ) { while ( uc < end && *uc != c ) uc++; } else { c = ::lower( c ); while ( uc < end && ::lower( *uc ) != c ) uc++; } if ( uint(uc - unicode()) >= l ) return -1; return (int)(uc - unicode());}/* an implementation of the Boyer-Moore search algorithm*//* initializes the skiptable to know haw far ahead we can skip on a wrong match*/static void bm_init_skiptable( const QString &pattern, uint *skiptable, bool cs ){ int i = 0; register uint *st = skiptable; int l = pattern.length(); while ( i++ < 0x100/8 ) { *(st++) = l; *(st++) = l; *(st++) = l; *(st++) = l; *(st++) = l; *(st++) = l; *(st++) = l; *(st++) = l; } const QChar *uc = pattern.unicode(); if ( cs ) { while ( l-- ) { skiptable[ uc->cell() ] = l; uc++; } } else { while ( l-- ) { skiptable[ ::lower( *uc ).cell() ] = l; uc++; } }}static int bm_find( const QString &str, int index, const QString &pattern, uint *skiptable, bool cs ){ const uint l = str.length(); if ( pattern.isEmpty() ) return index > (int)l ? -1 : index; const QChar *uc = str.unicode(); const QChar *puc = pattern.unicode(); const uint pl = pattern.length(); const uint pl_minus_one = pl - 1; register const QChar *current = uc + index + pl_minus_one; const QChar *end = uc + l; if ( cs ) { while ( current < end ) { uint skip = skiptable[ current->cell() ]; if ( !skip ) { // possible match while ( skip < pl ) { if ( *(current - skip ) != puc[pl_minus_one-skip] ) break; skip++; } if ( skip > pl_minus_one ) { // we have a match return (current - uc) - skip + 1; } // in case we don't have a match we are a bit inefficient as we only skip by one // when we have the non matching char in the string. if ( skiptable[ (current-skip)->cell() ] == pl ) skip = pl - skip; else skip = 1; } current += skip; } } else { while ( current < end ) { uint skip = skiptable[ ::lower( *current ).cell() ]; if ( !skip ) { // possible match while ( skip < pl ) { if ( ::lower( *(current - skip) ) != ::lower( puc[pl_minus_one-skip] ) ) break; skip++; } if ( skip > pl_minus_one ) // we have a match return (current - uc) - skip + 1; // in case we don't have a match we are a bit inefficient as we only skip by one // when we have the non matching char in the string. if ( skiptable[ ::lower(*(current - skip)).cell() ] == pl ) skip = pl - skip; else skip = 1; } current += skip; } } // not found return -1;}#define REHASH( a ) \ if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \ hashHaystack -= (a) << sl_minus_1; \ hashHaystack <<= 1/*! \overload Finds the first occurrence of the string \a str, starting at position \a index. If \a index is -1, the search starts at the last character, if it is -2, at the next to last character and so on. (See findRev() for searching backwards.) If \a cs is TRUE (the default), the search is case sensitive; otherwise the search is case insensitive. Returns the position of \a str or -1 if \a str could not be found.*/int QString::find( const QString& str, int index, bool cs ) const{ const uint l = length(); const uint sl = str.length(); if ( index < 0 ) index += l; if ( sl + index > l ) return -1; if ( !sl ) return index;#if defined(Q_OS_MACX) && defined(QT_MACOSX_VERSION) && QT_MACOSX_VERSION >= 0x1020 if ( sl == 1 ) return find( *str.unicode(), index, cs );#endif // we use the Boyer-Moore algorithm in cases where the overhead // for the hash table should pay off, otherwise we use a simple // hash function if ( l > 500 && sl > 5 ) { uint skiptable[0x100]; bm_init_skiptable( str, skiptable, cs ); return bm_find( *this, index, str, skiptable, cs ); } /* We use some hashing for efficiency's sake. Instead of comparing strings, we compare the hash value of str with that of a part of this QString. Only if that matches, we call ucstrncmp or ucstrnicmp. */ const QChar* needle = str.unicode(); const QChar* haystack = unicode() + index; const QChar* end = unicode() + (l-sl); const uint sl_minus_1 = sl-1; uint hashNeedle = 0, hashHaystack = 0, i; if ( cs ) { for ( i = 0; i < sl; ++i ) { hashNeedle = ((hashNeedle<<1) + needle[i].unicode() ); hashHaystack = ((hashHaystack<<1) + haystack[i].unicode() ); } hashHaystack -= (haystack+sl_minus_1)->unicode(); while ( haystack <= end ) { hashHaystack += (haystack+sl_minus_1)->unicode(); if ( hashHaystack == hashNeedle && ucstrncmp( needle, haystack, sl ) == 0 ) return haystack-unicode(); REHASH( haystack->unicode() ); ++haystack; } } else { for ( i = 0; i < sl; ++i ) { hashNeedle = ((hashNeedle<<1) + ::lower( needle[i].unicode() ).unicode() ); hashHaystack = ((hashHaystack<<1) + ::lower( haystack[i].unicode() ).unicode() ); } hashHaystack -= ::lower(*(haystack+sl_minus_1)).unicode(); while ( haystack <= end ) { hashHaystack += ::lower(*(haystack+sl_minus_1)).unicode(); if ( hashHaystack == hashNeedle && ucstrnicmp( needle, haystack, sl ) == 0 ) return haystack-unicode(); REHASH( ::lower(*haystack).unicode() ); ++haystack; } } return -1;}/*! \fn int QString::findRev( const char* str, int index ) const Equivalent to findRev(QString(\a str), \a index).*//*! \fn int QString::find( const char* str, int index ) const \overload Equivalent to find(QString(\a str), \a index).*//*! \overload Finds the first occurrence of the character \a c, starting at position \a index and searching backwards. If the index is -1, the search starts at the last character, if it is -2, at the next to last character and so on. Returns the position of \a c or -1 if \a c could not be found. If \a cs is TRUE (the default), the search is case sensitive; otherwise the search is case insensitive. \code QString string( "bananas" ); int i = string.findRev( 'a' ); // i == 5 \endcode*/int QString::findRev(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -