用Qt基础库处理文本

使用Qt

Qt是跨平台的C++应用程序开发框架,广泛用于开发界面程序。Qt不仅仅是个强大的界面库,它的基础库同样强大,很多库用起来比STL还方便,所以我经常用Qt编写控制台(console)程序。本文介绍如何用Qt处理文本。

从文件逐行读取

例如,数据保存在文本文件中,每行一个数字:

1
2
3
4
5
1.0987
1.2910
1.5019
1.9981
...

标准的代码流程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
QFile infile("data.txt");          // 打开文件
if (!infile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Openning file failed!";
return;
}

QTextStream in(&infile);
while (!in.atEnd()) { // 直到文件末尾
QString line = in.readLine(); // 读取一行
line = line.trimmed(); // 忽略首尾的空白符
float data = line.toFloat(); // 根据需求转换
// ...
}

infile.close(); // 记得关闭文件

代码中的QIODevice::Text表示将Windows风格的换行符\r\n和Linux风格的换行符\n统一转换为标准的\n

分割单行文本

大多数场景下,一行内容会包含多条信息,用空白字符隔开,例如:

1
2
3
4
0.81945 -0.262967 0.0276042
0.816997 -0.064756 -0.105701
0.833224 -0.285919 -0.245202
...

我们需要将每一行内容拆分,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
QFile infile("data.txt");
if (!infile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Openning file failed!";
return;
}

QTextStream in(&infile);
while (!in.atEnd()) {
QString line = in.readLine();
// 以空白符为分隔符拆分一行
QStringList list = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);
// 各就各位
float yaw = list[0].toFloat();
float pitch = list[1].toFloat();
float roll = list[2].toFloat();
// ...
}

infile.close();

split函数的第一个参数指定分隔符,QRegExp("\\s+")是正则表达式,匹配所有空白字符(空格符、制表符等)。

逐行写入文件

将上面格式的数据写回到文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
QFile outfile("output.txt");
if (!outfile.open(QIODevice::ReadWrite | QFile::Truncate)) {
qDebug() << "Openning file failed!";
return;
}

QTextStream ts(&outfile);
for (int row = 0; row < NROWS; ++row) {
float yaw = data[row][0];
float pitch = data[row][1];
float roll = data[row][2];
ts << yaw << "\t" << pitch << "\t" << roll << endl; // 分隔符为制表符
}

outfile.close();

open函数打开写入的目标文件,参数一般需加上QFile::Truncate选项,将文件的内容清空。endl表示换行,在Windows系统下对应\r\n,在Linux系统下对应\n