将边列表解析为结构的向量

时间:2015-12-05 00:13:58

标签: c++ parsing vector

我很难用c ++中的文本文件解析边缘列表。边缘列表采用以下格式:

*Edgeslist
1 6487
2 6488 6489 6490 6491 6492 6493 6494 6495 6496
3 6497 6498 6499 6500 6501 6502 6503 6504 6505
4 6506 6507 6508
5 6509 6510 6511
6 6512 6513 6514 6515
7 6516
8 6517 6518
9 6519 6520
10 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535
11 6566

我的向量是这里定义的结构的向量

struct Edge{
int character;
int edges[16];
};

每行的第一个数字应该读入字符整数,其余的应该读入edge数组。我已经尝试了一些for循环,并且当前正在处理一个冗长的while循环,其中if语句用于每个可能的整数进入数组(在第一个数字后每行最多15个整数)。这是我实施的一部分,因此您可以看到我正在尝试的内容。

while(std::getline(input, line))
{
  int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o;
  std::stringstream ss(line);
  if ( ss >> a)
  {
       std::cout << "1 " << a << "\n";
  }
  if ( ss >> a >> b)
  {
       std::cout << "2 " << a << " " << b << "\n";
  }
  if ( ss >> a >> b >> c)
  {
       std::cout << "3 " << a << " " << b << " " << c << "\n";
  }
  if ( ss >> a >> b >> c >> d)
  {
       std::cout << "4 " << a << " " << b << " " << c << " " << d << "\n";
  }

我会在那里结束它,但它会持续一段时间,直到它涵盖所有可能的行。 目前我只想弄清楚解析这个文本文件的基本逻辑。

3 个答案:

答案 0 :(得分:0)

您应该将字符串拆分为空格中的子字符串。细节在这里解释。

之后,您只需将子字符串转换为适当的类型。

答案 1 :(得分:0)

std::stringstream ss(line);
ss >> character;
unsigned int n=0;
while(ss >> edges[n])
{
  ++n;
}

(人们可以把它缩短一点,但这样会降低它的可读性。)

答案 2 :(得分:0)

您已将其标记为C ++。

如果您必须继续使用pod,我建议您添加初始化程序。

struct Edge
{
   int character;
   int edges[16];
   //  more data attributes

   // use ctor to initialize these values
   Edge(void) :
      character (0)
      // edges[16] 
   { 
      for (int i=0; i<16; ++i)
         edges[i] = 0;
   }


   // use dtor to clear them
  ~Edge(void)
   { 
      for (int i=0; i<16; ++i)
         edges[i] = 0;
      character = 0;
      // ...
   }

};

我怀疑你还需要计算当前安装了多少条边(或者称之为nextIn)。

C ++代码的基本重要签名是对象定义的首选用法。我建议你考虑一下:

struct Edge
{
   int character;               // poor name choice
   std::vector<int> edges;      // << use vector, not array

   // use ctor to initialize these values
   Edge(void) :
      character (0)
      // edges   // default ctor does what you need
   { 
   }

   ~Edge(void) {
       // edges default dtor does what you need
       character = 0;
    }
};

std :: vector减少了你读取任意值的工作量。

// Typical input:
// 3 6497 6498 6499 6500 6501 6502 6503 6504 6505
// 4 6506 6507 6508

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>

struct Edge
{
   int character;               // <<< poor name choice
   std::vector<int> edges;      // <<< use vector, not array

   // use ctor to initialize these values
   Edge(void) :
      character (0)
      // edges  default ctor does what you need
      {
      }

   ~Edge(void) {
      // edges default dtor does what you need
      character = 0;
   }

   bool ok(void) {
      /*tbd - count errors? size check? */
      return(true);
   };

   void load(std::string line)
      {
         // typical input line
         // 3 6497 6498 6499 6500 6501 6502 6503 6504 6505
         // 4 6506 6507 6508

         std::stringstream ss(line+' ');
         // padding at end ---------^----because ss.eof() sooner than I expected

         //debug only
         //std::cout << "  in: (" << std::setw(3) << line.size() << ") 
         //          << line << std::endl;

         // process one work buff
         do {

            ss >> character; // read 1st int of line

            if (ss.eof()) break;

            if (ss.bad()) {
               // maybe invalid integer format
               std::cerr << "bad input: " << line << std::endl;
               // tbd - error count?
               break;
            }

            // process 1 or more entries for edge.vector from line
            do {

               int edgeVal = 0;

               ss >> edgeVal;

               if (ss.eof()) break;

               if (ss.bad()) {
                  // maybe invalid integer format
                  std::cerr << "bad input: " << line << std::endl;
                  // tbd - error count?
                  break;
               }

               // additional edgeVal validations?

               edges.push_back(edgeVal);  // fill in one value to edge vector

               // add validation here if edges.size() has an upper limit
               // tbd - error count?

            } while (1); // // process 1 or more entries to vector from line
         } while(1); // one work buff

         // debug only
         dump();

      }  // void load(std::stringstream& ss, std::string line)

   // for debug 
   void dump()
      {
         std::cout << "dump: (" << std::setw(3) << edges.size()
                   << ")  " << character << " ";

         for (size_t i=0; i<edges.size(); ++i)
            std::cout << edges[i] << " ";
         std::cout << std::endl;
      }

};  // struct Edge()



int t237(void)
{
   std::vector<Edge> edgeVec;

   // file processing at outer scope
   do {

      std::string line; // work buff

      (void)std::getline(std::cin, line);

      if(std::cin.eof()) break;

      std::stringstream ss(line);

      Edge temp; // a work buff

      temp.load(line); // <<< load method for Edge (part of Edge)

      // not sure where to put all the Edge objects
      // temporarily, use edgeVec;
      if (temp.ok())   // add flag check that edgeVec had no errors
         edgeVec.push_back(temp);
      else
         /*tbd*/{};  // error in temp ... discard it? report it?

   } while (1);

   // tbd - how return vector and file status

   return (0);
}

----更新

ss.eof()在我预期之前发生...添加了“padding at end” 添加了dump()调试方法,添加了输入行的调试cout

最小化测试完成