C++ 讀protel電路網表程序,用於邊界掃描互聯網絡測試

寫了一個簡單的讀電路網表的程序,把每個互聯網絡的網絡名和結點提取出來,得到的信息用於邊界掃描互連網絡測試。
不同軟件公司的網表文件格式不同,以下代碼僅能讀protel的電路網表。
protel的電路網表後綴是.NET,格式如下圖:

在這裏插入圖片描述
器件信息:
在這裏插入圖片描述
網絡信息:
在這裏插入圖片描述

#include <iostream>
#include <fstream>
#include <sstream>
#include <regex>
#include <vector>
#include <string>
#include <list>

using namespace std;

int main()
{
    // 一個網絡全部信息存在一個vector<string>中
    vector<vector<string>> netListInfo;
    // 存放器件名稱及類型
    vector<vector<string>> componentName;

    // 實現把網表文件一次全部讀入到string裏:
    // 把網表文件讀入文件流對象
    // 把文件流對象的內容給string流
    // 把string流對象所保存的內容的拷貝賦給netListFileContent
    ifstream inFile_NetList("C:/Users/10057/Desktop/BStest.NET");
    //ifstream inFile_NetList("C:/Users/10057/Desktop/STM32.NET");
    ostringstream temp;
    temp << inFile_NetList.rdbuf();
    string netListFileContent = temp.str();

    // 定義正則表達式
    regex bracketBeg("\\(");
    //   regex bracketEnd("\\)");
    regex squareBracketBeg("\\[");
    //regex squareBracketEnd("\\]");
    // 結點:網絡名-引腳
 //regex netInfo("^[[:alpha:]]{1,2}[[:digit:]]{1,2}-[[:digit:]]{1,2}");


 // 提取器件信息
    for (sregex_iterator it(netListFileContent.begin(), netListFileContent.end(), squareBracketBeg), end_it; it != end_it; ++it)
    {
        // 把 [ 後的200個char放入temp中
        auto pos = it->suffix().str().length();
        pos = pos > 200 ? 200 : pos;
        string temp = it->suffix().str().substr(1, pos);
        string::iterator it_str = temp.begin();

        // 如果迭代器it還沒指向 ] ,就說明這個器件信息還沒讀完
        vector<string> temp_vector;
        int i = 0;
        while (*it_str != ']')
        {
            string temp_string;
            while (*it_str != '\n')
            {
                // 第0行是器件名,最後一行(第二行)是產品類型
                if ((i == 0) | (i == 2))
                {
                    char temp_char = *it_str;
                    temp_string = temp_string + temp_char;
                }
                ++it_str;

            }
            // 如果是0、2行,就存下來
            if ((i == 0) | (i == 2))
            {
                temp_vector.push_back(temp_string);
            }
            // 跳出循環,此時 *it_str = '\n',需要讓迭代器指向下一個char
            ++it_str;
            // 行數+1
            ++i;
        }
        // 第i個器件信息已存完
        componentName.push_back(temp_vector);
        // 讓迭代器指向temp末尾,免得它亂跑
        it_str = temp.end();
    }

    // 輸出器件信息
    for (int i = 0; i != componentName.size(); ++i)
    {
        for (int j = 0; j != componentName[i].size(); ++j)
        {
            cout << componentName[i][j] << " ";
        }
        cout << endl;
    }



    // 提取網絡信息
    for (sregex_iterator it(netListFileContent.begin(), netListFileContent.end(), bracketBeg), end_it; it != end_it; ++it)
    {
        // 把 ( 後的500個char放入temp中
        auto pos = it->suffix().str().length();
        pos = pos > 500 ? 500 : pos;
        string temp = it->suffix().str().substr(1, pos);
        string::iterator it_str = temp.begin();

        // 如果迭代器it還沒指向 ) ,就說明這個網絡的結點還沒讀完
        vector<string> temp_vector;
        while (*it_str != ')')
        {
            // 第0行是網絡名,後面一行是一個結點
            string temp_string;
            while (*it_str != '\n')
            {
                char temp_char = *it_str;
                temp_string = temp_string + temp_char;
                ++it_str;

            }
            temp_vector.push_back(temp_string);
            // 跳出循環,此時 *it_str = '\n',需要讓迭代器指向下一個char
            ++it_str;
        }
        // 第i個網絡信息已存完
        netListInfo.push_back(temp_vector);
        // 讓迭代器指向temp末尾,免得它亂跑
        it_str = temp.end();
    }

    // 輸出
    for (int i = 0; i != netListInfo.size(); ++i)
    {
        for (int j = 0; j != netListInfo[i].size(); ++j)
        {
            cout << netListInfo[i][j] << " ";
        }
        cout << endl;
    }


    system("pause");
}

在寫這個這麼簡單的程序的時候遇到了如下問題(寫這部分就是想記錄一下調試的時候遇到的問題):
(1) vector subscript out of range(容器下標越界)。
比如:

// 初始化二維容器,沒有給容器設定初始大小,因爲我想動態往裏面添元素
 vector<vector<string>> netListInfo;
 // 我得到字符串之後,直接用下標訪問方式給容器賦值。
 // 這句當然是錯的,因爲容器初始大小爲0,
 // 直接用下標[0][0]訪問,是給一個不存在的地方賦值,是下標越界。
 netListInfo[0][0]="abc";
 // 解決方法:用.push_back()函數吧。
 // 二維容器的話,可以先用一個一維容器vector<string>暫存你的內容,
 // 然後再把這個一維容器push_back到二維容器中去。

(2)string是可以動態改變大小的(但好多博客說不可以,我覺得可以的吖)。
比如:

 // 定義一個string
 string  temp_string ;
  // 定義並初始化一個char
 char temp_char = 'a';
 // 把'a'添加進string
 temp_string = temp_string + temp_char;
 // 定義並初始化一個char
char temp_char2 = 'b';
 // 把'b'添加進string
 // 這不就是可以動態改變string大小嗎,
 // 定義string的時候沒有初始化大小,然後再一點一點往裏面添元素
  temp_string = temp_string + temp_char2;
  // 注意這裏寫成temp_string +=  temp_char2;編譯不通過,
  // 但 temp_string = temp_string + temp_char2;就是對的,我也不知道爲什麼

運行結果:
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章