[英]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.