从文件C ++中读取

时间:2011-10-19 20:39:10

标签: c++

您好我想将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

我不知道如何做到这一点,因为我必须在数组之间添加数字。

3 个答案:

答案 0 :(得分:5)

为此目的,我再次无法抵抗使用Boost Spirit的手指练习。

说明

看到这个非常特殊和简约的样本

  • 将给定文本(使用Spirit Qi)解析为

    • 点数集合(对矢量)
    • 查找表的动态映射(由名称标识 - 例如“压力”)并包含向量)
  • 对未预期的输入进行基本错误报告

  • 将解析后的数据打印回紧凑格式(这使用Spirit Karma

  • 它是空白容忍的(尽管输入中需要换行符)

缺陷:

  • 它真的很快又脏:它应该是a grammar class
    • 单独的规则定义
      • 更具可读性
      • more debuggable
    • 显式语义输入检查(查找表名称,每个数据表中的元素数量(POINTS _ nPOINT_DATA n中的计数现在被忽视了。)
    • 使用phoenix(或c ++ 0x 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;
}