2012-07-26 305 views
6

我正在讀取一個文件中的字符串,因此它的格式爲char數組。我需要標記字符串並將每個char數組標記保存爲數組中的一個uint8_t十六進制值。從字符串轉換爲uint8_t的數組?

char* starting = "001122AABBCC"; 
// ... 
uint8_t[] ending = {0x00,0x11,0x22,0xAA,0xBB,0xCC} 

如何從starting轉換爲ending?謝謝。

+1

嘿@Nirav,它看起來像一個幾個答案下面幫助您解決問題。如果是這種情況,那麼最好接受你最喜歡的答案(用答案左邊的複選框)。你可以(或將能夠有足夠的聲譽)[投票](http://stackoverflow.com/privileges/vote-up)所有有用的答案。 – 2012-07-30 13:12:44

回答

0

uint8_t通常不超過unsigned char的typedef。如果您正在讀取文件中的字符,您應該可以像讀取已簽名的字符數組一樣將它們讀入unsigned char數組,並且unsigned char數組的一個uint8_t數組。

+0

請注意,@ Nirav正試圖將表示十六進制字符串的ASCII字符轉換爲整數值。 – 2012-07-26 20:53:09

+0

這會給你ascii值ox 0,x,1-9,A-F不是十六進制字符的值 – 2012-07-26 20:53:38

+0

對,謝謝你指出。 – pinerd314159 2012-07-26 20:54:01

0

我想嘗試這樣的事:

std::string starting_str = starting; 
uint8_t[] ending = new uint8_t[starting_str.length()/2]; 
for (int i = 0 ; i < starting_str.length() ; i+=2) { 
    std::string pair = starting_str.substr(i, i+2); 
    ending[i/2] = ::strtol(pair.c_str(), 0, 16); 
} 

沒有測試它,但它看起來不錯,我...

+0

謝謝,strtol函數是我無法弄清楚的部分! – 2012-07-27 13:26:57

1

strtoul將文本轉換在您選擇到字節的任何基地。你必須做一些工作來將輸入字符串斬成單個數字,或者一次可以轉換32或64位。

PS uint8_t[] ending = {0x00,0x11,0x22,0xAA,0xBB,0xCC}

並不意味着什麼,你是不是將數據存儲在UINT8爲「十六進制」,要存儲字節,它高達你(或你調試器)如何interpretes二進制數據

+0

不錯!如果一次轉換32位或64位,是否存在序列位置問題? – 2012-07-26 20:54:44

+0

@rob - 可能! – 2012-07-27 00:23:39

+0

謝謝,stroul函數的工作 – 2012-07-27 13:28:09

2

這是一個完整的工作程序。它基於Rob I的解決方案,但修復了幾個問題已經過測試。

#include <string> 
#include <stdio.h> 
#include <stdlib.h> 
#include <vector> 
#include <iostream> 


const char* starting = "001122AABBCC"; 
int main() 
{ 
    std::string starting_str = starting; 
    std::vector<unsigned char> ending; 
    ending.reserve(starting_str.size()); 
    for (int i = 0 ; i < starting_str.length() ; i+=2) { 
     std::string pair = starting_str.substr(i, 2); 
     ending.push_back(::strtol(pair.c_str(), 0, 16)); 
    } 

    for(int i=0; i<ending.size(); ++i) { 
     printf("0x%X\n", ending[i]); 
    } 

} 
1

用C++ 11,你可以使用std::stoi爲:

std::vector<uint8_t> convert(const std::string& s) 
{ 
    if (s.size() % 2 != 0) { 
     throw std::runtime_error("Bad size argument"); 
    } 
    std::vector<uint8_t> res; 
    res.reserve(s.size()/2); 
    for (std::size_t i = 0, size = s.size(); i != size; i += 2) { 
     std::size_t pos = 0; 
     res.push_back(std::stoi(s.substr(i, 2), &pos, 16)); 
     if (pos != 2) { 
      throw std::runtime_error("bad character in argument"); 
     } 
    } 
    return res; 
} 

Live example

-1
uint8_t* ending = static_cast<uint8_t*>(starting); 
0

你可以從一組焦炭添加自己的轉換{ '0', '1',...... 'E', 'F'}到uint8_t

uint8_t ctoa(char c) 
{ 
    if(c >= '0' && c <= '9') return c - '0'; 
    else if(c >= 'a' && c <= 'f') return 0xA + c - 'a'; 
    else if(c >= 'A' && c <= 'F') return 0xA + c - 'A'; 
    else return 0; 
} 

然後,它會很容易將字符串轉換到數組:

uint32_t endingSize = strlen(starting)/2; 
uint8_t* ending = new uint8_t[endingSize]; 

for(uint32_t i=0; i<endingSize; i++) 
{ 
    ending[i] = (ctoa(starting[i*2]) << 4) + ctoa(starting[i*2+1]); 
} 
1

我認爲,任何規範的答案(WRT恩惠音符)將涉及在溶液中的一些不同的階段:爲有效輸入

  • 長度檢測和
  • 數據內容檢查
  • 元素轉換
  • 輸出創建

    • 錯誤檢查

    鑑於th這種轉換的有用性,解決方案應該包括一些靈活性w.r.t.所使用的類型和所需的語言環境。

    從一開始,考慮到「更正規答案」的請求日期(2014年8月左右),將自由使用C++ 11。

    代碼的註釋版本,與對應於OP類型:

    std::vector<std::uint8_t> convert(std::string const& src) 
    { 
        // error check on the length 
        if ((src.length() % 2) != 0) { 
        throw std::invalid_argument("conversion error: input is not even length"); 
        } 
    
        auto ishex = [] (decltype(*src.begin()) c) { 
        return std::isxdigit(c, std::locale()); }; 
    
        // error check on the data contents 
        if (!std::all_of(std::begin(src), std::end(src), ishex)) { 
        throw std::invalid_argument("conversion error: input values are not not all xdigits"); 
        } 
    
        // allocate the result, initialised to 0 and size it to the correct length 
        std::vector<std::uint8_t> result(src.length()/2, 0); 
    
        // run the actual conversion  
        auto str = src.begin(); // track the location in the string 
        std::for_each(result.begin(), result.end(), [&str](decltype(*result.begin())& element) { 
        element = static_cast<std::uint8_t>(std::stoul(std::string(str, str + 2), nullptr, 16)); 
        std::advance(str, 2); // next two elements 
        }); 
    
        return result; 
    } 
    

    代碼的模板版本增加了靈活性;

    std::vector<std::uint8_t> convert(std::string const& src) 
    { 
        return basic_convert<std::uint8_t>(src, std::locale()); 
    } 
    

    Live sample

    template <typename Int /*= std::uint8_t*/, 
        typename Char = char, 
        typename Traits = std::char_traits<Char>, 
        typename Allocate = std::allocator<Char>, 
        typename Locale = std::locale> 
    std::vector<Int> basic_convert(std::basic_string<Char, Traits, Allocate> const& src, Locale locale = Locale()) 
    { 
        using string_type = std::basic_string<Char, Traits, Allocate>; 
    
        auto ishex = [&locale] (decltype(*src.begin()) c) { 
         return std::isxdigit(c, locale); }; 
    
        if ((src.length() % 2) != 0) { 
        throw std::invalid_argument("conversion error: input is not even length"); 
        } 
    
        if (!std::all_of(std::begin(src), std::end(src), ishex)) { 
        throw std::invalid_argument("conversion error: input values are not not all xdigits"); 
        } 
    
        std::vector<Int> result(src.length()/2, 0); 
    
        auto str = std::begin(src); 
        std::for_each(std::begin(result), std::end(result), [&str](decltype(*std::begin(result))& element) { 
        element = static_cast<Int>(std::stoul(string_type(str, str + 2), nullptr, 16)); 
        std::advance(str, 2); 
        }); 
    
        return result; 
    } 
    

    convert()功能如下然後可以基於該basic_convert()

  • 0

    這種簡單的解決辦法應該適用於您的問題

    char* starting = "001122AABBCC"; 
    uint8_t ending[12]; 
    
    // This algo will work for any size of starting 
    // However, you have to make sure that the ending have enough space. 
    
    int i=0; 
    while (i<strlen(starting)) 
    { 
        // convert the character to string 
        char str[2] = "\0"; 
        str[0] = starting[i]; 
    
        // convert string to int base 16 
        ending[i]= (uint8_t)atoi(str,16); 
    
        i++; 
    }