我目前正在尝试将字符读入如下类
struct data {
string segment; string name;
double length; double radius; double wall_thickness;
double young_modulus; double compliance;
};我还有一个向量,它包含以下元素:
2A
Aorta_Ascendens
2
1.47
.164
4
53.4
2B
Aorta_Ascendens
2
1.44
.161
4
51.0
3A我想在文本文件中读取每个部分,目前这是我的算法,通过文本文件连续读取,并分别添加每个部分。
int place = 0;
while (place != temp_data.size()){
int counter = 0;
for (counter; counter <= 7; ++counter){
istringstream is(temp_data[place + counter]);
if (counter == 0){ is >> a.segment; }
if (counter == 1){ is >> a.name; }
if (counter == 2){ is >> a.length; }
if (counter == 3){ is >> a.radius; }
if (counter == 4){ is >> a.wall_thickness; }
if (counter == 5){ is >> a.young_modulus; }
if (counter == 6){ is >> a.compliance; }
}
counter = counter - 1; //since the next segment is at temp_data[7], must subtract one to have place = 7.
place = counter + place;
v.push_back(a);
}我遇到的问题是设法确保文本的正确部分进入对象的正确部分。对于前七行文本,对象应该如下所示:
segment: 2A
name: Aorta_Ascendens
length: 2
radius: 1.47
wall_thickness: .164
young modulus: 4
compliance: 53.4这应该在整个文本文件中以相同的方式重复。temp_data是一个包含需要添加到对象中的元素的向量,但是我找不到一种好的方法来不断地遍历向量并将元素放在正确的位置。
我提出的算法有一个计数器和一个位置保持器,计数器将通过向量点循环,在这种情况下,位置保持器将保持第一个对象的数据成员的位置。在算法的末尾,位置应该等于temp_data的大小,然后退出循环。但是,当它编译和运行时,我遇到了问题,它似乎把错误的元素放入了错误的对象成员中。
有什么想法吗?
发布于 2013-12-17 00:53:36
一种简单、干净的方法是编写一个自定义流操作符:
struct data {
string segment; string name;
double length; double radius; double wall_thickness;
double young_modulus; double compliance;
friend std::istream& operator>>(std::istream& is, data& d)
{
return is >> d.segment >> d.name >> d.length >> d.radius >> d.wall_thickness
>> d.young_modulus >> d.compliance;
}
};没有temp_data,istringstream或counter。
要使用此方法:
data d;
while (input_stream >> d)
v.push_back(d);
if (input_stream.fail())
...print error / exit or whatver...
else
...use v...(有更多的声明性方法可以使用标准算法和back_inserter迭代器将流复制到向量,但是IMHO简单而明显的方法是好的)
发布于 2013-12-17 00:36:01
您可以使用更经典的方法来使用文件格式的映射(也就是说,如果您能够访问文件的规范(内容))。
您已经给出了您的文本应该是什么样子的完美示例:
segment: 2A
name: Aorta_Ascendens
length: 2
radius: 1.47
wall_thickness: .164
young modulus: 4
compliance: 53.4这种格式有什么问题?因此,它提供了更好的灵活性(安全性),因为您可以检查成员是否是您希望阅读的内容。可以用分隔符分隔对象:
segment: 2A
name: Aorta_Ascendens
length: 2
radius: 1.47
wall_thickness: .164
young modulus: 4
compliance: 53.4
**@**
segment: 2B
name: Aorta_Ascendens
length: 3
radius: 1.00
wall_thickness: .164
young modulus: 4
compliance: 53.4使用ifstream.readlines()获取一个C++样式字符串数组,这将帮助您使用find()函数进行解析(如果没有找到,则返回string::npos )。
在Parse()函数中,它涉及对文件行的迭代,首先,使用find查找:字符,然后使用substr来检查要分配值的成员(以及如何解析、整数、枚举?)和另一个有一点计算的substr (如size - posfound),把它放在你选择的lexical_cast中。无论是boost::lexial_cast还是std::istringstream。
否则,您可以选择使用boost::serialization,这将只允许您编写一个超级简单的函数来读取这种格式。(比照附件)
或者更复杂的数据绑定框架,比如代码综合XSD (Xerces?):
http://www.codesynthesis.com/products/xsd/
更简单的是,使用python。你只需要做eval()
PS:附件(与boost::serialization一起)摘自文档:
class gps_position
{
private:
friend class boost::serialization::access;
// When the class Archive corresponds to an output archive, the
// & operator is defined similar to <<. Likewise, when the class Archive
// is a type of input archive the & operator is defined similar to >>.
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & degrees;
ar & minutes;
ar & seconds;
}
int degrees;
int minutes;
float seconds;
public:
gps_position(){};
gps_position(int d, int m, float s) :
degrees(d), minutes(m), seconds(s)
{}
};这不是很简单吗?并保证它能起作用。(只要您使用相同的序列化程序编写该文件)。
请参阅0/libs/serialization/doc/index.html
https://stackoverflow.com/questions/20623506
复制相似问题