2008-11-09 257 views
1

我想從命令行讀取mac id並將其轉換爲uint8_t值的數組以在結構中使用它。我無法讓它工作。我有一個關於:的mac id分割的字符串向量,我想用stringstream將它們轉換爲沒有運氣。我錯過了什麼?C++將mac id字符串轉換爲uint8_t數組

int parseHex(const string &num){ 
    stringstream ss(num); 
    ss << std::hex; 
    int n; 
    ss >> n; 
    return n; 
} 

uint8_t tgt_mac[6] = {0, 0, 0, 0, 0, 0}; 
    v = StringSplit(mac , ":"); 
    for(int j = 0 ; j < v.size() ; j++){ 
    tgt_mac[j] = parseHex(v.at(j)); 
    } 

回答

0

我認爲你正在使用的std ::六角放錯了地方:

#include <sstream> 
#include <iostream> 

int main() 
{ 
    std::string  h("a5"); 
    std::stringstream s(h); 
    int x; 

    s >> std::hex >> x; 
    std::cout << "X(" << x << ")\n"; 
} 
+0

當我做了COUT INT解析功能,我得到正確的值,但是當我將它們分配到uint8_t數組他們搞的一團糟。我試過你的建議它在函數中工作,但他們仍然搞砸了,當我分配他們。 – 2008-11-09 17:22:27

1

你的問題可能是在分析數據的輸出。 「< <」運算符根據傳遞的數據類型決定如何顯示數據,而uint8_t可能會被解釋爲char。確保在打印時將數組值轉換爲整數,或者在調試器中進行調查。

示例程序:

uint8_t tgt_mac[6] = {0}; 
std::stringstream ss("AA:BB:CC:DD:EE:11"); 
char trash; 

for (int i = 0; i < 6; i++) 
{ 
    int foo; 
    ss >> std::hex >> foo >> trash; 
    tgt_mac[i] = foo; 
    std::cout << std::hex << "Reading: " << foo << std::endl; 
} 

std::cout << "As int array: " << std::hex 
    << (int) tgt_mac[0] 
    << ":" 
    << (int) tgt_mac[1] 
    << ":" 
    << (int) tgt_mac[2] 
    << ":" 
    << (int) tgt_mac[3] 
    << ":" 
    << (int) tgt_mac[4] 
    << ":" 
    << (int) tgt_mac[5] 
    << std::endl; 
std::cout << "As unint8_t array: " << std::hex 
    << tgt_mac[0] 
    << ":" 
    << tgt_mac[1] 
    << ":" 
    << tgt_mac[2] 
    << ":" 
    << tgt_mac[3] 
    << ":" 
    << tgt_mac[4] 
    << ":" 
    << tgt_mac[5] 
    << std::endl; 

提供了以下輸出(Cygwin的G ++)

Reading: aa 
Reading: bb 
Reading: cc 
Reading: dd 
Reading: ee 
Reading: 11 
As int array: aa:bb:cc:dd:ee:11 
As unint8_t array: ª:»:I:Y:î:◄ 
2

首先,我想指出,我認爲@史蒂芬的答案是非常好的一個 - 事實上我注意到相同:值是正確的,但輸出看起來很尷尬。這是由於使用了ostream& operator<<(ostream&, unsigned char),因爲您使用的uint8_t類型是unsigned char的typedef(正如我在Linux手冊頁中找到的那樣)。請注意,在VC++中,typedef不存在,您必須使用unsigned __int8(這也將引導您到char專業化)。

接下來,你可以測試你這樣的代碼(輸出無關):

assert(uint8_t(parseHex("00")) == uint8_t(0)); 
assert(uint8_t(parseHex("01")) == uint8_t(1)); 
//... 
assert(uint8_t(parseHex("ff")) == uint8_t(255)); 

除了史蒂芬的答案,我只是想指出transform算法的存在,這可能仍簡化您的代碼。

for(int j = 0 ; j < v.size() ; j++){ 
    tgt_mac[j] = parseHex(v.at(j)); 
} 

寫在一行:

std::transform(v.begin(), v.end(), tgt_mac, &parseHex); 

(我知道有沒有用的問題做...)

(它所然後看起來像見codepad.org

3

我不喜歡用這種方式回答這個問題,但sscanf()可能是解析MAC地址的最簡潔的方法。它處理零/非零填充,寬度檢查,大小寫摺疊以及所有其他沒有人喜歡處理的內容。無論如何,這是我沒有那麼C++版本:

void 
parse_mac(std::vector<uint8_t>& out, std::string const& in) { 
    unsigned int bytes[6]; 
    if (std::sscanf(in.c_str(), 
        "%02x:%02x:%02x:%02x:%02x:%02x", 
        &bytes[0], &bytes[1], &bytes[2], 
        &bytes[3], &bytes[4], &bytes[5]) != 6) 
    { 
     throw std::runtime_error(in+std::string(" is an invalid MAC address")); 
    } 
    out.assign(&bytes[0], &bytes[6]); 
}