Qt读取文本文件的一些信息



我有一个.txt文件,需要从中读取。该文件包括城市的数据,他们的经度,纬度和其他一些东西。

这是数据格式:

DE  01945   **Tettau**  Brandenburg BB      00  Landkreis Oberspreewald-Lausitz 12066   **51.4333   13.7333**
DE  01968   **Schipkau Hörlitz**    Brandenburg BB      00  Landkreis Oberspreewald-Lausitz 12066   **51.5299   13.9508**
...

文件的每一行都是一个城市,但对我来说,只有粗体信息很重要(名称、纬度、经度(。总而言之,文件中有 16k 行。 你能解释一下我是如何获得这些信息的吗?

QFile file ("path");
QTextStream in (&file);
while (!in.atEnd()) {
QString line = in.readLine();
std::string s = line.toLocal8Bit().constData();
std::cout << s << endl;
}
file.close();

到目前为止,我只能阅读整行,但我不知道如何获取每行的这 3 条信息。 我创建了一个包含三个成员的类"城市"。_name、_longitude、_latitude。然后我想创建一个矢量来保护里面的每个城市。这种方法有效吗? 但更重要的是,请告诉我如何阅读每行的 3 条粗体信息,因为我不知道该怎么做。(我想遍历字符串的每个字符并搜索制表符,但花了很长时间(。 所以如果你告诉我一个快速的方法,我真的很高兴。Programm是用Qt和c++开发的。

PS:我还注意到一个问题,即一些城市名称由 2 个单词组成,用空格分隔。

您拥有的文件是制表符分隔值 (TSV(,因此逻辑是获取每一行并通过制表符分隔,然后选择如下所示的元素:

#include <QFile>
#include <QTextStream>
#include <iostream>
struct CityData
{
std::string city;
float latitude;
float longitude;
};
int main()
{
QFile file("/path/of/DE.txt");
if(!file.open(QFile::ReadOnly | QFile::Text))
return -1;
QTextStream stream(&file);
QString line;
std::vector<CityData> datas;
while (stream.readLineInto(&line)) {
QStringList elements = line.split("t");
CityData data{elements[2].toStdString(),
elements[9].toFloat(),
elements[10].toFloat()
};
datas.push_back(data);
}
for(const CityData & data: datas){
std::cout<< "city: "<< data.city <<"t" << "latitude: "<< data.latitude <<"t" << "longitude: "<<data.longitude<<"n";
}
return 0;
}

输出:

city: Tettau    latitude: 51.4333   longitude: 13.7333
city: Guteborn  latitude: 51.4167   longitude: 13.9333
city: Hermsdorf latitude: 51.4055   longitude: 13.8937
city: Grünewald latitude: 51.4  longitude: 14
city: Hohenbocka    latitude: 51.431    longitude: 14.0098
city: Lindenau  latitude: 51.4  longitude: 13.7333
city: Ruhland   latitude: 51.4576   longitude: 13.8664
city: Schwarzbach   latitude: 51.45 longitude: 13.9333
city: Kroppen   latitude: 51.3833   longitude: 13.8
city: Schipkau Hörlitz  latitude: 51.5299   longitude: 13.9508
city: Senftenberg   latitude: 51.5252   longitude: 14.0016
city: Schipkau  latitude: 51.5456   longitude: 13.9121
...

在这种类型的材料中,您应该阅读readme.txt

...
The data format is tab-delimited text in utf8 encoding, with the following fields :
country code      : iso country code, 2 characters
postal code       : varchar(20)
place name        : varchar(180)
admin name1       : 1. order subdivision (state) varchar(100)
admin code1       : 1. order subdivision (state) varchar(20)
admin name2       : 2. order subdivision (county/province) varchar(100)
admin code2       : 2. order subdivision (county/province) varchar(20)
admin name3       : 3. order subdivision (community) varchar(100)
admin code3       : 3. order subdivision (community) varchar(20)
latitude          : estimated latitude (wgs84)
longitude         : estimated longitude (wgs84)
accuracy          : accuracy of lat/lng from 1=estimated to 6=centroid

本质上,你只需要分隔你的行:

QStringList delimited = line.split(" ");
QString town = delimited[2];

为了在您的示例中获得 Tettau 或 Schipkau,其他项目也是如此。

也就是说,我不确定你例子中的"Schipkau Hörlitz"是什么,假设这是一个城镇或一个城镇的四分之一的名称,有一个组合的名字。这取决于您的格式。一种选择是从索引 2 开始,添加任何内容,只要它不是德国国家的名称。当然,这只适用于德国。您也可以尝试找出下一个只有数字的索引,在您的示例中"00",然后从该索引开始工作。同样,这取决于你的格式,我希望我给了你足够的工作。

可能如下所示:

QStringList delimited = line.split(" ");
QString town = delimited[2];
size_t pos = 3;
while(not is_german_state(delimited[pos]))
{
town += " "  + delimited[pos];
pos++;
}
QString longitude = delimited[pos+6];
QString latitude= delimited[pos+7];

(请注意,我没有发现当一行格式不正确并因此分隔[pos]或经度或纬度的行时的情况,否则可能会导致分段错误。

之后,您可以以某种方式存储它,例如具有存储所需数据的结构TownDatavector<TownData>,并在每次迭代中附加到向量。我认为如何做到这一点很清楚,但如果不是,请问

。在Qt中,一般来说,查看您当前使用的类是值得的。在这种情况下,QString,它具有很多功能。

由于向量在更改其预留大小时会复制它,并且您特别询问了效率,因此最好在进入迭代之前为向量保留足够的空间。我不知道有任何方法可以在不实际遍历的情况下获取文件中的行数,因此您可能需要在实际处理其中的数据之前执行此操作一次,或者您需要创建一些估计器,例如按文件大小估计行数或估计它是 16k。然后在向量上调用vector::reserve(size_type n)。也就是说,16k 行听起来并不多,可能是这是过早的优化。我可能会先不加保留地去,只是看看它是否按原样顺利运行。

相关内容

  • 没有找到相关文章

最新更新