C++ Qt读取文本文件的某些信息
我有一个C++ Qt读取文本文件的某些信息,c++,string,qt,file,qt5,C++,String,Qt,File,Qt5,我有一个.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-Laus
.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();
QFile文件(“路径”);
文件中的QTextStream(&F);
而(!in.atEnd()){
QString line=in.readLine();
std::string s=line.toLocal8Bit().constData();
std::cout本质上,您只需要划定您的界限:
QStringList delimited = line.split(" ");
QString town = delimited[2];
为了在您的示例中获得Tettau或Schipkau,其他项目也是如此
也就是说,我不确定“希普考·霍利茨”在您的示例中,假设这是一个城镇的名称或一个城镇的四分之一的名称,并使用组合名称。这取决于您的格式。一个选项是从索引2开始,添加任何名称,只要它不是德国的州名称。当然,这只适用于德国。您还可以尝试找出下一个索引that是唯一的数字,在你的例子中是“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]或经度或纬度的线可能会导致分段错误。)
然后你以某种方式存储它,比如有一个向量
,它的结构是TownData
,它存储你需要的数据,在每次迭代中,你都会附加到向量上。我假设如何做是清楚的,但问一下它是否不清楚
在Qt中,一般来说,查看您当前使用的类是值得的
由于向量在更改其保留大小时被复制,并且您特别询问了效率问题,因此在进入迭代之前为向量保留足够的空间是一个好主意。我不知道有任何方法可以获得文件中的行数,而不必实际迭代,因此您可能需要这样做在您实际处理其中的数据之前,或者您需要创建一些估计器,例如按文件大小估计行数或将其估计为16k。然后调用vector::reserve(size\u type n)
在你的向量上。也就是说,16k行听上去没有那么多,可能是因为这是过早的优化。我可能会先不做保留,简单地看看它是否运行正常。你拥有的文件是一个以制表符分隔的值(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;
}
在这类材料中,您应该阅读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
城市名称后面是单词Brandenburg,在代码ABCDE?之前,除了纬度和经度在行的末尾之外,最后你可以共享该文件。如果我知道如何在此处上传文件,我可以共享该文件:D。但我也可以共享该文件的链接。只需从geoc下载DE.zip,这是一个开源文件我尝试了你的建议,与你写的两行完全相同。程序编译后,但当我运行控制台时,我得到一个错误“在QList::operator[]中断言失败”:索引超出范围,文件C:\Qt\5.10.1\mingw53\u 32\include/QtCore/qlist.h,第行549@Domooo93可能是它读取了一行空行或类似内容。可能在每次迭代中都会检查该行。为了进行调试,您可能希望打印当前行和列表的大小。@domoo93,或者,正如另一个人所说的,使用制表符。谢谢大家,你们都能提供帮助我很抱歉,因为我的声望不到15,所以我无法将你的答案标记为有用,但我真的很感激:)@domoo93你应该能够选择一个并接受它作为答案,尽管(分数下的灰色复选标记)谢谢你们,你们两个都帮了我很多,我不能把你们的答案标记为有用的,因为我的声誉不到15,但我真的很感激:)@domoo93将答案标记为正确是一回事,另一件事是放弃投票。将回答标记为正确不一定是声誉,如果你不知道如何做,请这样做他,这是最好的感谢方式。@domoo93我已经给了你一票,所以你可以投一票,把我的答案记为正确。:)
...
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