您好我想将VTK文件中的数据读入我的C ++程序。 这是我的文件通常看起来的样子。
POINTS 2 double
1 2
3 4
POINT_DATA 2
SCALARS压力加倍
LOOKUP_TABLE默认
5
6
SCALARS密度加倍
LOOKUP_TABLE默认
7
8
我想将粗体中突出显示的数值数据放入我的C ++程序中,但我不知道如何忽略数据之间的文本行。
更确切地说:我有数组xp[2], yp[2], pressure[2] , density[2]
我想提出
xp[0]=1 yp[0]=2
xp[1]=3 yp[1]=4
pressure[0]=5 pressure[1]=6
density[0]=7 density[1]=8
我不知道如何做到这一点,因为我必须在数组之间添加数字。
答案 0 :(得分:5)
为此目的,我再次无法抵抗使用Boost Spirit的手指练习。
看到这个非常特殊和简约的样本
将给定文本(使用Spirit Qi)解析为
对未预期的输入进行基本错误报告
将解析后的数据打印回紧凑格式(这使用Spirit Karma)
它是空白容忍的(尽管输入中需要换行符)
缺陷:
POINTS
_ n
和POINT_DATA
n
中的计数现在被忽视了。)std::move
)来防止复制查找表数据如图所示输出代码/输入(注意有意'伪造'输入,显示错误报告):
Parse failed remaining: 'bogus'
Points: [1.0,2.0], [3.0,4.0]
density: 7.0, 8.0
pressure: 5.0, 6.0
代码(c ++,用boost 1_47_0测试):
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <map>
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
typedef std::vector<double> lookuptable_t;
typedef std::map<std::string, lookuptable_t> lookuptables_t;
typedef std::pair<double, double> point_t;
typedef std::vector<point_t> points_t;
int main()
{
std::string input =
"POINTS 2 double\n"
"1 2\n"
"3 4\n"
"POINT_DATA 2\n"
"SCALARS pressure double\n"
"LOOKUP_TABLE default\n"
"5\n"
"6\n"
"SCALARS density double\n"
"LOOKUP_TABLE default\n"
"7\n"
"8 bogus";
points_t points;
lookuptables_t lookuptables;
{
std::string::const_iterator f(input.begin()), l(input.end());
using namespace qi;
bool ok = phrase_parse(f, l,
"POINTS" > omit[ uint_ ] > "double" > eol >>
(double_ >> double_) % eol > eol >>
"POINT_DATA" > omit [ uint_ ],
char_(" \t"), points);
while (ok && f!=l)
{
std::string name;
lookuptable_t table;
ok = phrase_parse(f, l,
eol >> "SCALARS" > +raw [ eps >> "pressure"|"density" ] > "double" > eol >
"LOOKUP_TABLE" > "default" > eol >
double_ % eol,
char_(" \t"), name, table);
if (ok && !lookuptables.insert(std::make_pair(name, table)).second)
std::cerr << "duplicate table for '" << name << "' ignored" << std::endl;
}
if (!ok || (f!=l))
std::cerr << "Parse " << (ok?"success":"failed") << " remaining: '" <<
std::string(f, std::min(f+10, l)) << "'" << std::endl;
}
{
using namespace karma;
std::cout << format(
"Points: " << ('[' << double_ << ',' << double_ << ']') % ", " << eol <<
+(string << ": " << auto_ % ", " << eol),
points, lookuptables);
}
}
答案 1 :(得分:1)
您可以使用ignore
函数丢弃不是数字的文本行。使用cin >> x
从输入文件中读取值x。如果失败,则在输入流中设置failbit
,您必须clear
。然后,忽略整行。
std::vector<int> data;
while (!cin.eof())
{
int x;
if (cin >> x) {
data.push_back(x);
if (data.size() == 8)
{
// do whatever you need with the 8 numbers
data.clear();
}
} else {
cin.clear();
cin.ignore(1000, '\n'); // assuming maximum line length less than 1000
}
}
(此代码假定从cin
读取,并重定向到另一个输入文件)
答案 2 :(得分:0)
您可以尝试一些看起来像这样的代码。它是C和C ++的组合:
int main ()
{
//assuming that you've completely read in the file to a char* called myFileContents
char * token;
token = strtok (myFileContents," ");
while (token != NULL)
{
istringstream iss( token );
int readInData;
readInData << iss;
if(!iss){
//this means that the data wasn't numeric so don't do anything with it
}
else{
//data was numeric, store it how ever you want
}
token = strtok (NULL, " ");
}
return 0;
}