繁体   English   中英

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

[英]Parsing an edge list into a vector of structs

我很难从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];
};

每行的第一个数字应读入字符整数,其余的应读入edges数组。 我已经尝试了一些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";
  }

我将在此处结束,但是它会持续一段时间,直到覆盖所有可能的行。 目前,我只是想弄清楚解析此文本文件的基本逻辑。

您应该在空白处将字符串拆分为子字符串。 详细说明在这里。

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

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

(可以将其缩短一点,但这会使可读性降低。)

您已将此标签为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()在我预期之前发生...添加了“填充末尾”添加了dump()调试方法,添加了输入行的调试指令

最少的测试完成

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM