📄 qtextstream.cpp
字号:
}/*! Returns the current real number notation. \sa setRealNumberNotation(), realNumberPrecision(), numberFlags(), integerBase()*/QTextStream::RealNumberNotation QTextStream::realNumberNotation() const{ Q_D(const QTextStream); return d->realNumberNotation;}/*! Sets the precision of real numbers to \a precision. This value describes the number of fraction digits QTextStream should write when generating real numbers. \sa realNumberPrecision(), setRealNumberNotation()*/void QTextStream::setRealNumberPrecision(int precision){ Q_D(QTextStream); d->realNumberPrecision = precision;}/*! Returns the current real number precision, or the number of fraction digits QTextStream will write when generating real numbers. \sa setRealNumberNotation(), realNumberNotation(), numberFlags(), integerBase()*/int QTextStream::realNumberPrecision() const{ Q_D(const QTextStream); return d->realNumberPrecision;}/*! Returns the status of the text stream. \sa QTextStream::Status, setStatus(), resetStatus()*/QTextStream::Status QTextStream::status() const{ Q_D(const QTextStream); return d->status;}/*! \since 4.1 Resets the status of the text stream. \sa QTextStream::Status, status(), setStatus()*/void QTextStream::resetStatus(){ Q_D(QTextStream); d->status = Ok;}/*! \since 4.1 Sets the status of the text stream to the \a status given. \sa Status status() resetStatus()*/void QTextStream::setStatus(Status status){ Q_D(QTextStream); if (d->status == Ok) d->status = status;}/*! Returns true if there is no more data to be read from the QTextStream; otherwise returns false. This is similar to, but not the same as calling QIODevice::atEnd(), as QTextStream also takes into account its internal Unicode buffer.*/bool QTextStream::atEnd() const{ Q_D(const QTextStream); CHECK_VALID_STREAM(true); if (d->string) return d->string->size() == d->stringOffset; return d->readBuffer.isEmpty() && d->device->atEnd();}/*! Reads the entire content of the stream, and returns it as a QString. Avoid this function when working on large files, as it will consume a significant amount of memory. Calling readLine() is better if you do not know how much data is available. \sa readLine()*/QString QTextStream::readAll(){ Q_D(QTextStream); CHECK_VALID_STREAM(QString()); const QChar *readPtr; int length; if (!d->scan(&readPtr, &length, /* maxlen = */ 0, QTextStreamPrivate::EndOfFile)) return QString(); QString tmp = QString(readPtr, length); d->consumeLastToken(); return tmp;}/*! Reads one line of text from the stream, and returns it as a QString. The maximum allowed line length is set to \a maxlen. If the stream contains lines longer than this, then the lines will be split after \a maxlen characters and returned in parts. If \a maxlen is 0, the lines can be of any length. A common value for \a maxlen is 75. The returned line has no trailing end-of-line characters ("\\n" or "\\r\\n"), so calling QString::trimmed() is unnecessary. If the stream has read to the end of the file, the returned string will be an empty string. You can explicitly test for the end of the file using atEnd(). \sa readAll()*/QString QTextStream::readLine(qint64 maxlen){ Q_D(QTextStream); CHECK_VALID_STREAM(QString()); const QChar *readPtr; int length; if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfLine)) return QString(); QString tmp = QString(readPtr, length); d->consumeLastToken(); return tmp;}/*! \since 4.1 Reads at most \a maxlen characters from the stream, and returns the data read as a QString. \sa readAll(), readLine(), QIODevice::read()*/QString QTextStream::read(qint64 maxlen){ Q_D(QTextStream); CHECK_VALID_STREAM(QString()); if (maxlen <= 0) return QString::fromLatin1(""); // empty, not null const QChar *readPtr; int length; if (!d->scan(&readPtr, &length, int(maxlen), QTextStreamPrivate::EndOfFile)) return QString(); QString tmp = QString(readPtr, length); d->consumeLastToken(); return tmp;}/*! \internal*/QTextStreamPrivate::NumberParsingStatus QTextStreamPrivate::getNumber(qulonglong *ret){ scan(0, 0, 0, NotSpace); consumeLastToken(); // detect int encoding int base = integerBase; if (base == 0) { QChar ch; if (!getChar(&ch)) return npsInvalidPrefix; if (ch == QLatin1Char('0')) { QChar ch2; if (!getChar(&ch2)) { // Result is the number 0 *ret = 0; return npsOk; } ch2 = ch2.toLower(); if (ch2 == QLatin1Char('x')) { base = 16; } else if (ch2 == QLatin1Char('b')) { base = 2; } else if (ch2.isDigit() && ch2.digitValue() >= 0 && ch2.digitValue() <= 7) { base = 8; } else { base = 10; } ungetChar(ch2); } else if (ch == QLatin1Char('-') || ch == QLatin1Char('+') || ch.isDigit()) { base = 10; } else { ungetChar(ch); return npsInvalidPrefix; } ungetChar(ch); // State of the stream is now the same as on entry // (cursor is at prefix), // and local variable 'base' has been set appropriately. } qulonglong val=0; switch (base) { case 2: { QChar pf1, pf2, dig; // Parse prefix '0b' if (!getChar(&pf1) || pf1 != QLatin1Char('0')) return npsInvalidPrefix; if (!getChar(&pf2) || pf2.toLower() != QLatin1Char('b')) return npsInvalidPrefix; // Parse digits int ndigits = 0; while (getChar(&dig)) { int n = dig.toLower().unicode(); if (n == '0' || n == '1') { val <<= 1; val += n - '0'; } else { ungetChar(dig); break; } ndigits++; } if (ndigits == 0) { // Unwind the prefix and abort ungetChar(pf2); ungetChar(pf1); return npsMissingDigit; } break; } case 8: { QChar pf, dig; // Parse prefix '0' if (!getChar(&pf) || pf != QLatin1Char('0')) return npsInvalidPrefix; // Parse digits int ndigits = 0; while (getChar(&dig)) { int n = dig.toLower().unicode(); if (n >= '0' && n <= '7') { val *= 8; val += n - '0'; } else { ungetChar(dig); break; } ndigits++; } if (ndigits == 0) { // Unwind the prefix and abort ungetChar(pf); return npsMissingDigit; } break; } case 10: { // Parse sign (or first digit) QChar sign; int ndigits = 0; if (!getChar(&sign)) return npsMissingDigit; if (sign != QLatin1Char('-') && sign != QLatin1Char('+')) { if (!sign.isDigit()) { ungetChar(sign); return npsMissingDigit; } val += sign.digitValue(); ndigits++; } // Parse digits QChar ch; while (getChar(&ch)) { if (ch.isDigit()) { val *= 10; val += ch.digitValue(); } else { ungetChar(ch); break; } ndigits++; } if (ndigits == 0) return npsMissingDigit; if (sign == QLatin1Char('-')) { qlonglong ival = qlonglong(val); if (ival > 0) ival = -ival; val = qulonglong(ival); } break; } case 16: { QChar pf1, pf2, dig; // Parse prefix ' 0x' if (!getChar(&pf1) || pf1 != QLatin1Char('0')) return npsInvalidPrefix; if (!getChar(&pf2) || pf2.toLower() != QLatin1Char('x')) return npsInvalidPrefix; // Parse digits int ndigits = 0; while (getChar(&dig)) { int n = dig.toLower().unicode(); if (n >= '0' && n <= '9') { val <<= 4; val += n - '0'; } else if (n >= 'a' && n <= 'f') { val <<= 4; val += 10 + (n - 'a'); } else { ungetChar(dig); break; } ndigits++; } if (ndigits == 0) { return npsMissingDigit; } break; } default: // Unsupported integerBase return npsInvalidPrefix; } if (ret) *ret = val; return npsOk;}/*! \internal (hihi)*/bool QTextStreamPrivate::getReal(double *f){ // We use a table-driven FSM to parse floating point numbers // strtod() cannot be used directly since we may be reading from a // QIODevice. enum ParserState { Init = 0, Sign = 1, Mantissa = 2, Dot = 3, Abscissa = 4, ExpMark = 5, ExpSign = 6, Exponent = 7, Done = 8 }; enum InputToken { None = 0, InputSign = 1, InputDigit = 2, InputDot = 3, InputExp = 4 }; static uchar table[8][5] = { // None InputSign InputDigit InputDot InputExp { 0, Sign, Mantissa, Dot, 0 }, // Init { 0, 0, Mantissa, Dot, 0 }, // Sign { Done, Done, Mantissa, Dot, ExpMark }, // Mantissa { 0, 0, Abscissa, 0, 0 }, // Dot { Done, Done, Abscissa, Done, ExpMark }, // Abscissa { 0, ExpSign, Exponent, 0, 0 }, // ExpMark { 0, 0, Exponent, 0, 0 }, // ExpSign { Done, Done, Exponent, Done, Done } // Exponent }; ParserState state = Init; InputToken input = None; scan(0, 0, 0, NotSpace); consumeLastToken(); const int BufferSize = 128; char buf[BufferSize]; int i = 0; QChar c; while (getChar(&c)) { switch (c.unicode()) { case '+': case '-': input = InputSign; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': input = InputDigit; break; case '.': input = InputDot; break; case 'e': case 'E': input = InputExp; break; default: input = None; break; } state = ParserState(table[state][input]); if (state == Init || state == Done || i > (BufferSize - 5)) { ungetChar(c); if (i > (BufferSize - 5)) { // ignore rest of digits while (getChar(&c)) { if (!c.isDigit()) { ungetChar(c); break; } } } break; } buf[i++] = c.toLatin1(); } if (i == 0) return false; buf[i] = '\0'; if (f) *f = strtod(buf, 0); return true;}/*! Reads a character from the stream and stores it in \a c. Returns a reference to the QTextStream, so several operators can be nested. Example: \code QTextStream in(file); QChar ch1, ch2, ch3; in >> ch1 >> ch2 >> ch3; \endcode Whitespace is \e not skipped.*/QTextStream &QTextStream::operator>>(QChar &c){ Q_D(QTextStream); CHECK_VALID_STREAM(*this); d->scan(0, 0, 0, QTextStreamPrivate::NotSpace); if (!d->getChar(&c)) setStatus(ReadPastEnd); return *this;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -