c++ - 将边列表解析为结构 vector

标签 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

我的 vector 是这里定义的结构 vector

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

每行的第一个数字应该读入字符整数,其余的应该读入边缘数组。我已经尝试了几个 for 循环,目前正在使用 if 语句处理一个冗长的 while 循环,用于每个可能的整数进入数组(第一个数字后每行最多 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";
  }

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

最佳答案

您已将其标记为 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()调试方法,添加了输入行的调试cout

完成最小测试

关于c++ - 将边列表解析为结构 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34099621/

相关文章:

python - 在 C/openCL 中寻址 vector 元素

vector - 如何重写 Vec.append "in favor of"扩展?

尝试从 vector 中删除时,C++ 访问冲突读取位置 0x003AE000

用于绘制具有透明度的 2d 的 C++ 快速库

c++ - 在区分源代码、目标代码、汇编代码和机器代码时,我感到困惑

ios - JSON 字符串不会被解析

string - 在Go中逐行读取文件

java - 在递归中使用 += 在 Java 和 C++ 中产生不同的结果

c++ - 为什么 QPainter 不绘制到我的 QWidget?

javascript - 如何从公元第一年的 Javascript 字符串日期创建日期对象?