QTextStream可以在QIODevice、QByteArray或QString上操作。使用QTextStream的流操作符,您可以方便地读写单词、行和数字。对于生成文本,QTextStream支持字段填充和对齐的格式化选项,以及数字的格式化。例如:

  1. QFile data("output.txt");
  2. if (data.open(QFile::WriteOnly | QFile::Truncate)) {
  3. QTextStream out(&data);
  4. out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7;
  5. // writes "Result: 3.14 2.7 "
  6. }

QTextStream是区域设置感知的,并且会使用正确的编解码器自动解码标准输入。例如:

  1. QTextStream stream(stdin);
  2. QString line;
  3. while (stream.readLineInto(&line)) {
  4. // ...
  5. }

您可以通过调用seek()来寻找一个位置,当没有数据剩余可读时,atEnd()将返回true。如果你调用flush(), QTextStream将从它的写缓冲区清空所有数据到设备,并在设备上调用flush()。

默认情况下,QTextCodec::codecForLocale()用于读写,但你也可以通过调用setCodec()来设置编解码器。还支持自动Unicode检测。当此特性被启用(默认行为)时,QTextStream将检测UTF-16或UTF-32 BOM(字节顺序标记),并在读取时切换到适当的UTF编解码器。QTextStream默认不写BOM,但是你可以通过调用setGenerateByteOrderMark(true)来启用它。当QTextStream直接对QString操作时,编解码器被禁用。

有三种使用QTextStream读取文本文件的一般方法:

  • 一个块一个块地,调用readLine()readAll()
  • 逐字逐句地,QTextStream支持流到qstring, QByteArrays和char*缓冲区。 单词由空格分隔,前导空格会自动跳过。
  • 一个字符接一个字符,通过流进入QChar或char类型。 在解析文件时,这种方法通常用于方便的输入处理,与字符编码和行结束语义无关。 要跳过空白,调用skipWhiteSpace()。

因为文本流使用缓冲区,所以不应该使用超类的实现从流中读取。 例如,如果你有一个QFile,并直接使用QFile::readLine()而不是使用流来读取它,文本流的内部位置将与文件的位置不同步。

默认情况下,当从文本流中读取数字时,QTextStream将自动检测数字的基本表示形式。 例如,如果数字以“0x”开头,则假定为十六进制。 如果它从数字1-9开始,则假定它是十进制的,依此类推。 您可以通过调用setIntegerBase()来设置整数基数,从而禁用自动检测。 例子:

  1. QTextStream in("0x50 0x20");
  2. int firstNumber, secondNumber;
  3. in >> firstNumber; // firstNumber == 80
  4. in >> dec >> secondNumber; // secondNumber == 0
  5. char ch;
  6. in >> ch; // ch == 'x'
  7. qDebug() << ch;

QTextStream支持许多格式化选项来生成文本。

  • 通过调用setFieldWidth()和setPadChar()来设置字段宽度和填充字符。
  • 使用setFieldAlignment()设置每个字段的对齐方式。
  • 对于实数,调用setRealNumberNotation()和setRealNumberPrecision()设置生成数字的数字表示法(SmartNotation, ScientificNotation, FixedNotation)和精度。
  • 通过setNumberFlags()也可以提供一些额外的数字格式化选项。

1 设置数字的输出格式

可以使用QTextStream类的setNumberFlags方法,指定数字的输出格式,它的标志位含义介绍如下:

  • QTextStream::ShowBase 指定以哪一种进制进行显示,16 (“0x”), 8 (“0”), or 2 (“0b”)
  • QTextStream::ForcePoint 如果输出类型是double或float,若这个数字不含小数部分,默认情况下不显示小数部分,若设置了该标志位,则显示小数部分
  • QTextStream::ForceSign 在输出的数字前面加上正负号,即”+”或”-“
  • QTextStream::UppercaseBase 在进制指示中,使用大写字母表示,如”0X”, “0B”
  • QTextStream::UppercaseDigits 使用大写字母来表示10到35位数字,而不是小写。例如16进制中的a-f都用大写字母表示,或者科学计数法中的e使用大写E
  1. #include <QTextStream>
  2. int main(){
  3. QTextStream out(stdout);
  4. int i = 60;
  5. out.setIntegerBase(16); // 设置16进制显示,所以使用输入输出流,也可以很容易的进行 进制转换
  6. out << i << endl; // 3c
  7. out.setNumberFlags(out.numberFlags() | QTextStream::ShowBase);
  8. out << i << endl; // 0x3c
  9. out.setNumberFlags(out.numberFlags() | QTextStream::ForceSign);
  10. out << i << endl; // +0x3c
  11. out.setNumberFlags(out.numberFlags() | QTextStream::UppercaseBase);
  12. out << i << endl; // +0X3c
  13. double d = 100;
  14. out << d << endl; // +100
  15. out.setNumberFlags(QTextStream::ForcePoint);
  16. out << d << endl; // 100.000
  17. }

2 宽度,填充和对齐方式

2.1 宽度 可以调用setFieldWidth来设置输出流的宽度,所谓宽度是指,当在流中输出一个数时,至少产生宽度值所规定数量的字符。如果插入字符的个数小于宽度值,则用某个字符对空余的位置进行填充。

一定注意,这里的宽度是指定输出字符的最小数目,如果数目不够,则使用填充字符进行填充,而不会截断输出。如果你设置宽度为2时输出1234,仍会得到1234。

QTextStream的宽度设置与标准库的有一点不同,它不需要像标准库那样,在每一个输出符前都需要设置一次宽度。

2.2 对齐方式

对齐方式一般和宽度一起使用:

  • QTextStream::AlignLeft 左对齐
  • QTextStream::AlignRight 右对齐
  • QTextStream::AlignCenter 居中
  • QTextStream::AlignAccountingStyle 和AlignRight一样,只是数字的符号是左对齐的。 ```cpp

    include

int main(){ QTextStream out(stdout);

  1. int i = 60;
  2. out.setFieldWidth(6);
  3. out << i << endl; // output: 60
  4. out.setPadChar('-');
  5. out << i << endl; // output:----60
  6. out.setFieldAlignment(QTextStream::AlignLeft);
  7. out << i << endl; // output:60----
  8. out.setFieldAlignment(QTextStream::AlignRight);
  9. out << i << endl; // output:----60
  10. out.setFieldAlignment(QTextStream::AlignCenter);
  11. out << i << endl; // output:--60--
  12. out.setNumberFlags(QTextStream::ForceSign);
  13. out.setFieldAlignment(QTextStream::AlignAccountingStyle);
  14. out << i << endl; // output:+---60

}

  1. <a name="eh0Ub"></a>
  2. # 3 精度
  3. 请看下面的程序:
  4. ```cpp
  5. #include <QTextStream>
  6. int main(int argc, char *argv[])
  7. {
  8. QTextStream out(stdout);
  9. double d = 12.3456789;
  10. out << d << endl; // output:12.3457
  11. Q_ASSERT(d == 12.3456789);
  12. return 0;
  13. }

此程序预想的输出结果应该是12.3456789,但实际的输出结果是12.3457,那么,是d的值改变了吗。当然没有,因为Q_ASSERT测试为真。

这是因为QTextStream的精度默认设置为6,而如果想要改变它的默认精度,则可以使用setRealNumberPrecision方法。

  1. #include <QTextStream>
  2. int main(int argc, char *argv[])
  3. {
  4. QTextStream out(stdout);
  5. out.setRealNumberPrecision(10);
  6. double d = 12.3456789;
  7. out << d << endl; // output:12.3456789
  8. Q_ASSERT(d == 12.3456789);
  9. return 0;
  10. }