簡體   English   中英

如何使用uint8_t而不是char?

[英]How to work with uint8_t instead of char?

我希望了解有關uint8_t vs char,可移植性,位操作,最佳實踐,狀態等的情況。您是否對該主題有一個很好的閱讀?

我希望做byte-IO。 但是當然char比uint8_t有更復雜和微妙的定義; 我假設是引入stdint標頭的原因之一。

但是,我在多次使用uint8_t時遇到了問題。 幾個月前,曾經,因為沒有為uint8_t定義iostream。 是不是有一個C ++庫做了很好定義的字節IO,即讀寫uint8_t? 如果沒有,我認為沒有需求。 為什么?

我最近的頭痛源於此代碼編譯失敗:

uint8_t read(decltype(cin) & s)
{
    char c;
    s.get(c);
    return reinterpret_cast<uint8_t>(c);
}

error: invalid cast from type 'char' to type 'uint8_t {aka unsigned char}'

為什么錯誤? 如何使這項工作?

通用,便攜,往返正確的方式是:

  1. 在API中要求所有字節值最多可以用8位表示,
  2. 使用charsigned charunsigned char for I / O的布局兼容性,以及
  3. 根據需要將unsigned char轉換為uint8_t

例如:

bool read_one_byte(std::istream & is, uint8_t * out)
{
    unsigned char x;    // a "byte" on your system 
    if (is.get(reinterpret_cast<char *>(&x)))
    {
        *out = x;
        return true;
    }
    return false;
}

bool write_one_byte(std::ostream & os, uint8_t val)
{
    unsigned char x = val;
    return os.write(reinterpret_cast<char const *>(&x), 1);
}

一些解釋:規則1保證值可以在uint8_tunsigned char之間進行往返轉換,而不會丟失信息。 規則2意味着我們可以對unsigned char變量使用iostream I / O操作,即使它們是用char表示的。

我們也可以使用is.read(reinterpret_cast<char *>(&x), 1)而不是is.get()來進行對稱。 (通常使用read ,對於大於1的流計數,也需要在出錯時使用gcount() ,但這不適用於此。)

與往常一樣,您絕不能忽略I / O操作的返回值。 這樣做總是程序中的錯誤。

幾個月前,曾經,因為沒有為uint8_t定義iostream。

uint8_t幾乎只是unsigned char的typedef。 事實上,我懷疑你能找到一台並非如此的機器。

uint8_t read(decltype(cin) & s)
{
    char c;
    s.get(c);
    return reinterpret_cast<uint8_t>(c);
}

使用decltype(cin)而不是std::istream根本沒有任何優勢,它只是一個混亂的潛在來源。 return陳述中的演員陣容不是必要的; char轉換為unsigned char隱式地工作。

幾個月前,曾經,因為沒有為uint8_t定義iostream。

他們是。 不是uint8_t本身,但對於它實際代表的類型肯定是。 operator >>為unsigned char重載。 此代碼有效:

uint8_t read(istream& s)
{
    return s.get();
}

由於unsigned charchar可以互為別名,因此您也可以reinterpret_cast任何指向char字符串的指針reinterpret_cast指向unsigned char*並使用它。

如果您想要最便攜的方式,請查看Kerreks答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM