我有一个简单的课程City
,其中包含id
,name
,sizeOfPopulation
和坐标x
和y
。我有一个文本文件,如下所示:
City;1;Stockholm;300000;45;78;
City;2;Helsinky;451200;11;74;
City;3;Prague;897455;12;85;
每行代表以下内容:指标中的第一行,即城市。接下来是城市的ID,名称,人口规模,x和y。
我想阅读此文件并使用城市创建矢量。我知道,我需要重载运算符<<。
friend istream& operator >> (istream& is, City& c)
{
// I do not know
}
之后,我将能够从for
循环中的文件加载城市。你可以帮我解决一下超载运营商吗?
答案 0 :(得分:1)
像这样:
#include <istream>
#include <sstream>
friend istream& operator >> (istream& is, City& c)
{
// get whole line
string line;
if (!getline(is, line))
{
// error reporting and exit goes here...
}
// replace all ';' to ' '
for (int i = 0; i < line.length(); i++)
{
if (line[i] == ';')
line[i] = ' ';
}
// start parsing here
istringstream iss(line);
string tmp;
if (iss >> tmp >> c.id >> c.name >> sizeOfPopulation >> c.x >> c.y)
{
// error reporting and exit goes here...
}
return input;
}
要在循环中阅读City
个对象,您可以使用:
City c;
while (is >> c) // suppose "is" is the opened input stream
{
// successfully read a City, stored in c
}
答案 1 :(得分:0)
在这种情况下,我会使用getline
来读取该行,然后将其拆分
在';'
上使用类似的内容:
std::vector<std::string>
split( std::string const& source, char separ )
{
std::vector<std::string> results;
std::string::const_iterator start = source.begin();
std::string::const_iterator end = source.end();
std::string::const_iterator next = std::find( start, end, separ );
while ( next != end ) {
results.push_back( std::string( start, next ) );
start = next + 1;
next = std::find( start, end, separ );
}
results.push_back( std::string( start, end ) );
}
(您可能希望将其扩展为修剪前导和尾随 空间等。)
对于字符串的字段,您只需索引到
std::vector
;对于其他人,使用字符串值
初始化std::istringstream
以转换它们(或
std::stoi
,如果你有C ++ 11)。所以你最终会得到一些东西
像:
std::istream&
operator>>( std::istream& source, City& dest )
{
std::string record;
if ( std::getline( source, record ) ) {
std::vector<std::string> fields = split( record );
if ( fields.size() != 7 || fields[0] != "City" || fields[6] != "" ) {
source.setstate( std::ios_base::failbit );
} else {
try {
dest = City( std::stoi( vector[1] ),
std::vector[2],
std::stoi( vector[3] ),
Coordinates( std::stoi( vector[4] ),
std::stoi( vector[5]) ) ) );
catch ( ... ) {
source.setstate( std::ios_base::failbit );
}
}
}
return source;
}
(try ... catch
的需求并不是很好,但是那个
std::stoi
报告错误的方式。)