C++ 如何将类值指定给向量<;字符串>;?
我有一个很大的文本文件,其中每一行代表一个有邮政编码和州的城市。 它是这样写的:C++ 如何将类值指定给向量<;字符串>;?,c++,C++,我有一个很大的文本文件,其中每一行代表一个有邮政编码和州的城市。 它是这样写的: Brandenburg 35432 Potsdamm Niedersachsen 35698 Hannover 我已经阅读了向量中的文件,并且已经编写了一个类,希望将类值分配给向量 class City { private: float lat; //latitude float lon; //longitude public: City city
Brandenburg 35432 Potsdamm
Niedersachsen 35698 Hannover
我已经阅读了向量中的文件,并且已经编写了一个类,希望将类值分配给向量
class City
{
private:
float lat; //latitude
float lon; //longitude
public:
City cityclass(std::string state, std::string zipCode, std::string name);
//std::string name;
//std::string state;
//std::string zipCode;
float getLatitude() const
{
return lat;
}
float getLongitude() const
{
return lon;
}
};
因此,我有一个包含std::string zipCode、state和cityname的类。我认为这将是更好的工作,尤其是当我想能够搜索城市的邮政编码或名称。
我怎样才能意识到这一点?我想简单地修改我的while循环,如下所示,但我真的不确定这是否是一种方式。
这是我的全部代码:
class City
{
private:
/*float lat; //latitude
float lon; //longitude*/
public:
std::string zipCode;
std::string name;
std::string state;
/*float getLatitude() const
{
return lat;
}
float getLongitude() const
{
return lon;
}*/
};
int main ()
{
std::ifstream input("bundesland_plz_ort_de.txt");
//initilazing a vector of type string to store the data
std::vector<City> cityVector;
City city; //creating instance of class
//check if file can be accessed
if(!input)
{
std::cout << "ERROR!\tFile could not be opened!" << std::endl;
}
else
{
while(input >> city.state >> city.zipCode >> city.name)
{
cityVector.push_back(city);
}
input.close(); // close after finishing
}
}
class城市
{
私人:
/*浮动纬度;//纬度
float lon;//经度*/
公众:
std::字符串zipCode;
std::字符串名;
std::字符串状态;
/*浮点getLatitude()常量
{
返回lat;
}
float getLongitude()常量
{
返回离子;
}*/
};
int main()
{
std::ifstream输入(“bundesland_plz_ortu de.txt”);
//初始化字符串类型的向量以存储数据
std::矢量城市矢量;
City;//正在创建类的实例
//检查文件是否可以访问
如果(!输入)
{
std::cout city.state>>city.zipCode>>city.name)
{
城市导向器。推回(城市);
}
input.close();//完成后关闭
}
}
我建议采用稍微不同的方法。您定义了一个类City,但读取了该类之外的数据
C++中,我们应该把数据放在那些数据上的操作上,所有的操作都在一个类中。在这种情况下,您将(在您的类中)覆盖inserter和extractor操作符。这个类知道如何读写它的数据。即使稍后更改算法,其余代码也可以不经修改地工作
在下面的示例代码中,我放置了一个超简单的提取器和插入器(无错误检查)。从源文件读取所有数据只是一个简单的语句 它是使用其范围构造函数将变量“cl”定义为std::vector
。非常简短
std::vector的范围构造函数的用法
我们可以在没有模板参数的情况下定义std::vector。编译器可以从给定的函数参数推断参数。此功能称为CTAD(“类模板参数推断”)
此外,您可以看到,我没有明确地使用“end()”-迭代器
此迭代器将从空括号内的初始值设定项列表中构造,类型正确,因为由于std::vector构造函数需要,它将被推断为与第一个参数的类型相同
如前所述修改类后,您可以使用std库中的所有算法
请参阅:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <fstream>
struct City {
// Data
std::string state{};
std::string zipCode{};
std::string name{};
// Member functions
// Extractor
friend std::istream& operator >> (std::istream& is, City& c) {
return is >> c.state >> c.zipCode >> c.name;
}
// Inserter
friend std::ostream& operator << (std::ostream& os, const City& c) {
return os << "\nState: " << c.state << "\nZip Code: " << c.zipCode << "\nName: " << c.name;
}
};
int main() {
// Try to open file and check, if it worked
if (std::ifstream sourceFile("r:\\bundesland_plz_ort_de.txt"); sourceFile) {
// Read complete source file into a city list
std::vector cl(std::istream_iterator<City>(sourceFile), {});
// Give some Debug output
std::copy(cl.begin(), cl.end(), std::ostream_iterator<City>(std::cout, "\n"));
}
else {
std::cerr << "\nError: Source file could not be opened\n";
}
}
#包括
#包括
#包括
#包括
#包括
#包括
结构城市{
//资料
std::字符串状态{};
std::字符串zipCode{};
std::字符串名{};
//成员函数
//提取器
friend std::istream&operator>>(std::istream&is,City&c){
返回值为>>c.state>>c.zipCode>>c.name;
}
//插入器
friend std::ostream&operator我推荐一种稍有不同的方法。您定义了一个类城市,但您读取的数据不在类中
在C++中,我们应该把数据放在那些在数据上运行的操作中,所有的都在一个类中。在这种情况下,你将(在你的类中)覆盖插入器和提取器操作符。该类知道,如何读取和写入它的数据。即使你在稍后改变算法,其余的代码也将不修改。
在下面的示例代码中,我放置了一个超简单的提取器和插入器(无错误检查)。从源文件读取所有数据只需一条简单的语句
这是变量“cl”的定义,即使用其范围构造函数将其定义为std::vector
。非常简短
std::vector的范围构造函数的用法
我们可以在没有模板参数的情况下定义std::vector。编译器可以从给定的函数参数推断参数。此功能称为CTAD(“类模板参数推断”)
此外,您可以看到,我没有明确地使用“end()”-迭代器
此迭代器将从空括号内的初始值设定项列表中构造,类型正确,因为由于std::vector构造函数需要,它将被推断为与第一个参数的类型相同
如前所述修改类后,您可以使用std库中的所有算法
请参阅:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <fstream>
struct City {
// Data
std::string state{};
std::string zipCode{};
std::string name{};
// Member functions
// Extractor
friend std::istream& operator >> (std::istream& is, City& c) {
return is >> c.state >> c.zipCode >> c.name;
}
// Inserter
friend std::ostream& operator << (std::ostream& os, const City& c) {
return os << "\nState: " << c.state << "\nZip Code: " << c.zipCode << "\nName: " << c.name;
}
};
int main() {
// Try to open file and check, if it worked
if (std::ifstream sourceFile("r:\\bundesland_plz_ort_de.txt"); sourceFile) {
// Read complete source file into a city list
std::vector cl(std::istream_iterator<City>(sourceFile), {});
// Give some Debug output
std::copy(cl.begin(), cl.end(), std::ostream_iterator<City>(std::cout, "\n"));
}
else {
std::cerr << "\nError: Source file could not be opened\n";
}
}
#包括
#包括
#包括
#包括
#包括
#包括
结构城市{
//资料
std::字符串状态{};
std::字符串zipCode{};
std::字符串名{};
//成员函数
//提取器
friend std::istream&operator>>(std::istream&is,City&c){
返回值为>>c.state>>c.zipCode>>c.name;
}
//插入器
friend std::ostream&operator继续
首先通过一个循环获得对象的大致数目,然后在该循环之前计算以空格分隔的字符串的总数,然后除以成员数据的数目
// ...
//City city; //creating instance of class
if(!input)
{
std::cout << "ERROR!\tFile could not be opened!" << std::endl;
}
else if (input.is_open()) {
string buf(25);
int i=0;
while( input >> buf) ++i;
std::vector<City> cityVector(i /3 +5); // the number of member data plus some extra for sureness
input.clear();
input.seekg(0, ios::beg); // point back to start
i=0;
while( input >> cityVector[i].state >> cityVector[i].zipCode >> cityVector[i].name) ++i;
input.close(); // close after finishing
}
//..
/。。。
//City;//正在创建类的实例
如果(!输入)
{
标准:cout-buf)+i;
std::vector cityVector(i/3+5);//成员数据的数量加上一些额外的数据以确保
input.clear();
input.seekg(0,ios::beg);//指向后面开始
i=0;
while(输入>>cityVector[i].state>>cityVector[i].zipCode>>cityVector[i].name)++i;
input.close();//完成后关闭
}
//..
这种方法需要提前估计阵列大小,再加上一些保护量,然后可以调整大小,重新安装,例如调整cityVector.resize(i+1)
继续
首先获取