struct DataValue
{
DataValue() : uiQuality(0) {} // Here 0 stands for good.
unsigned int uiQuality;
std::string timeChanged;
float value;
};
std::vector<DataValues> myDataValues
在我的应用程序中的某个时刻,我的向量中的数据被填充。我正在使用下面的文件写一个文件。
std::ofstream myfile("myData.txt", std::ios::app);
for (int j = 0; j < myDataValues.size(); j++)
{
std::string quality;
if(myDataValues[j].quality == 0) {
quality = "good";
}
else {
quality = "bad";
}
myfile << myDataValues[j].timeChanged.c_str() << " " << myDataValues[j].value << " " << quality << std::endl;
}
文件如下所示。
2012-06-25 12:41:56.789 55 good
2012-06-25 12:51:14.782 55 good
2012-06-25 05:25:16.456 62.6925 good
2012-06-25 05:26:11.458 63.4109 good
2012-06-25 05:27:01.459 63.0383 good
2012-06-25 05:27:56.959 61.5266 good
2012-06-25 05:29:01.959 58.5354 good
2012-06-25 05:32:06.963 47.5656 good
2012-06-25 05:33:06.964 44.9916 good
2012-06-25 05:33:11.963 44.8267 good
2012-06-25 05:34:06.965 43.6011 good
2012-06-25 05:34:56.965 43.493 good
2012-06-25 12:51:14.782 52.418 good
2012-06-25 09:49:54.112 0 good
2012-06-25 11:50:30.781 0 good
现在我必须在其他应用程序中阅读上面的文件并填充另一个向量例如。填充向量是否重复,不需要此检查。
std::vector<DataValues> anotherDataValues
请求示例代码如何从上面的文件中读取数据并填充上面的矢量?
我该如何有效地做到这一点。
感谢您的时间和帮助。
答案 0 :(得分:2)
显而易见的方法是编写>>
(和<<
)运算符
班级。插入操作符非常简单:
std::ostream&
operator<<( std::ostream& dest, DataValue const& data )
{
dest << data.timeChanged << " "
<< data.value << " "
<< (data.uiQuality == 0 ? "good" : "bad");
return dest;
}
完成此操作后,只需编写:
即可输出数组std::copy( myDataValues.begin(), myDataValues.end(),
std::ostream_iterator<DataValue>( myFile, "\n" ) );
<<
运算符有点棘手,因为你必须要处理
格式中可能存在错误。鉴于数据格式包含
空格,我强加一个`\ n'作为终结符,并执行类似的操作:
std::istream&
operator>>( std::istream& source, DataValue& dest )
{
std::string line;
if ( std::getline( source, line ) ) {
std::istringstream parse( line );
std::string date;
std::string time;
float value;
std::string status;
parse >> date >> time >> value >> status >> std::ws;
if ( ! parse || (status != "good" && status != "bad") ) {
source.setstate( std::ios_base::failbit );
} else {
dest.timeChanged = date + ' ' + time;
dest.value = value;
dest.uiQuality = (status == "good" ? 0 : 1);
}
}
return source;
}
请注意,日期格式中的空格会使事情变得复杂。如果你
有一些控制格式,我摆脱它。 (ISO使用'T'
例如,分开日期和时间。)无论如何,使用一些
DataTime
的一类是有道理的;当然,这堂课
提供自己的>>
和<<
,然后您可以在上面使用它。
一旦你完成了这一点,阅读也变得微不足道了:
std::vector<DataValue> v(
(std::istream_iterator<DataValue>( myFile )),
(std::istream_iterator<DataValue>()) );
(注意额外的括号。至少有一个论点是必要的 避免最尴尬的解析问题。)
答案 1 :(得分:1)
您应首先弄清楚如何阅读一个 DataValue对象。然后填充它们的矢量很容易。以下是您可能会这样做的方法(尽管您应该提供更全面的错误检查)。
std::istream & operator>>(std::istream & is, DataValue & dv) {
std::string date, time, quality;
float value;
if (is >> date >> time >> value >> quality) {
if (quality == "good")
dv.uiQuality = 0;
else if (quality == "bad")
dv.uiQuality = 1;
else {
is.setstate(std::ios::failbit);
return is;
}
dv.timeChanged = date + " " + time;
dv.value = value;
}
return is;
}
然后,你可以像这样填充矢量:
std::ifstream fin("myData.txt");
std::istream_iterator<DataValue> beg(fin), end;
std::vector<DataValue> v(beg,end);
答案 2 :(得分:0)
显然你可以在stl向量上push_back
。但是,如果你这样做,并知道你的矢量有多长。您还可以使用reserve
函数来请求存储足够的空间,以便不需要调整向量的大小。
或者,您也可以使用resize
函数调用,并填写已经具有所需大小的stl向量。
http://www.cplusplus.com/reference/stl/vector/
您还可以从ifstream的getline
功能
http://www.cplusplus.com/reference/iostream/istream/getline/