【引例】
在FDDB人脸库中,因为该库是对人脸做了准确标记的库,所以每张脸都有个关于椭圆的参数。
样本:“123.583300 85.549500 1.265839 269.693400 161.781200 1”,遇到了这样的一个规范的内容进行提取的问题,数据之间用空格隔开。这些数值分别代表:center.x,center.y ,angle,长轴长,短轴长和分数。这个当然对于大牛的大家一定不是个问题,但是我试了一些方法,strtok函数和string中的find和substr结合的方法并且还是有boost中的正则的方法。虽然都能解决但是比较麻烦,并且有些语句读起来非常难以理解,实用率也不是非常高。
今天就了解字符串流的作用,并解决上述问题。
【遇到的问题】
1.中间的所间隔的空格数目不定。
2.分割之后需要把string类型转换到double类型才可以应用,并且很多情况需要根据不同的需要来进行不同类型的转换,使用atoi、atod等方法来进行转换,实在是麻烦。
【知识内容】
- <sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。
- 如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法。
- 由于需要输出的类型在编译期就确定了,所以编译器拥有足够的信息来判断需要哪些转换。<sstream>库中声明的标准类就利用了这一点,自动选择所必需的转换。而且,转换结果保存在stringstream对象的内部缓冲中。你不必担心缓冲区溢出,因为这些对象会根据需要自动分配存储空间。
【解决代码】
这个就是需要解析的文件结构,首先是图像名称,之后是人脸个数,接下来就是3个椭圆参数和分数。
string markDir = "D:/FaceDatabase/FDDB/FDDB_mark/";
string mark;
string markName = "FDDB-fold-01-ellipseList";
string markFormat = ".txt";
mark = markDir+markName+markFormat;
ifstream infile(mark);
if(!infile)
cerr<<"error open file";
string imageName,temp,facePos;
double x,y,angel,max_minor,min_minor,score; //椭圆5个参数和分数参数
while(getline(infile,imageName)){
getline(infile,temp);
int faceNum = atoi(temp.c_str()); //利用atoi方法来进行string到int的转换
while(faceNum--){
getline(infile,facePos);
stringstream fp(facePos);
fp>>x>>y>>angel>>max_minor>>min_minor>>score;//直接把这个流赋值到各个参数变量即可
}
}