Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt读取文本文件的某些信息_C++_String_Qt_File_Qt5 - Fatal编程技术网

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