簡體   English   中英

atoi() 等效於 intptr_t/uintptr_t

[英]atoi() equivalent for intptr_t/uintptr_t

C++(C++11,如果有區別)中是否有一個函數可以將字符串轉換為uintptr_tintptr_t 我總是可以使用atoll()並在之后進行轉換,但是如果能得到一個在 32 位機器上執行 32 位而在 64 位機器上執行 64 位的函數會很好。

char* c = "1234567";
uintptr_t ptr = atoptr(c); // a function that does this;

這是 C++ 中 IMO 令人驚訝的差距。 雖然stringstream完成這項工作,但對於如此簡單的任務來說,它是一個相當沉重的工具。 相反,您可以編寫一個內聯函數,根據類型大小調用strtoul的正確變體。 由於編譯器知道正確的大小,因此可以很聰明地將對該函數的調用替換為對 strtoul 或 strtoull 的調用。 即,類似於以下內容:

    inline uintptr_t handleFromString(const char *c, int base = 16)
    {
         // See if this function catches all possibilities.
         // If it doesn't, the function would have to be amended
         // whenever you add a combination of architecture and
         // compiler that is not yet addressed.
         static_assert(sizeof(uintptr_t) == sizeof(unsigned long)
             || sizeof(uintptr_t) == sizeof(unsigned long long),
             "Please add string to handle conversion for this architecture.");

         // Now choose the correct function ...
         if (sizeof(uintptr_t) == sizeof(unsigned long)) {
             return strtoul(c, nullptr, base);
         }

         // All other options exhausted, sizeof(uintptr_t) == sizeof(unsigned long long))
         return strtoull(c, nullptr, base);
    }

如果您決定更改手柄的類型,這將很容易更新。 如果你喜歡尖括號,你也可以用模板做一些等效的事情,盡管我看不出這會更清楚。

最后,您還可以使用%tx格式的sscanf ,即

inline uintptr_t handleFromString(const char *c)
{
   ptrdiff_t h;
   sscanf(c, "%tx", &h); // only hex supported, %td for decimal.
   return (uintptr_t)h;
}

不幸的是,我在 Compiler Explorer 上嘗試過的編譯器都沒有設法以刪除對 sscanf 調用的方式優化代碼。

暫無
暫無

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

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