سؤال

أريد تحويل hex string إلى 32 بت صحيح وقعت في C++.

لذا, فعلى سبيل المثال, يجب hex string "fffefffe".تمثيل ثنائي هذا هو 11111111111111101111111111111110.وقعت تمثيل صحيح هذا هو:-65538.

كيف أفعل هذا التحويل في C++?وهذا يحتاج أيضا إلى عمل غير الأرقام السالبة.على سبيل المثال, hex string "0000000A" ، وهو 00000000000000000000000000001010 في الثنائية ، 10 في عشري.

هل كانت مفيدة؟

المحلول

استخدام std::stringstream

unsigned int x;   
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;

المثال التالي تنتج -65538 نتيجة:

#include <sstream>
#include <iostream>

int main() {
    unsigned int x;   
    std::stringstream ss;
    ss << std::hex << "fffefffe";
    ss >> x;
    // output it as a signed type
    std::cout << static_cast<int>(x) << std::endl;
}

في C++11 القياسية ، هناك عدد قليل من فائدة جديدة من الوظائف التي يمكنك استخدام!على وجه التحديد ، هناك عائلة من "السلسلة إلى عدد" وظائف (http://en.cppreference.com/w/cpp/string/basic_string/stol و http://en.cppreference.com/w/cpp/string/basic_string/stoul).هذه هي أساسا رقيقة مغلفة حول ج السلسلة إلى عدد التحويل الوظائف ، ولكن تعرف كيف تتعامل مع std::string

حتى أبسط إجابة على أحدث رمز ربما تبدو مثل هذا:

std::string s = "0xfffefffe";
unsigned int x = std::stoul(s, nullptr, 16);

ملاحظة: أدناه هو بلدي الأصلي الجواب ، والتي تحرير يقول لا إجابة كاملة.من أجل حل عملي عصا القانون فوق الخط :-).

يبدو أنه منذ lexical_cast<> ويعرف أن يكون تيار التحويل من دلالات.للأسف تيارات لا تفهم "0x" التدوين.لذلك كل من boost::lexical_cast و يدي توالت واحد لا تتعامل بشكل جيد مع عرافة السلاسل.الحل أعلاه والتي يدويا مجموعات تيار الإدخال إلى عرافة والتعامل معها على ما يرام.

زيادة بعض الاشياء للقيام بذلك وكذلك بعض لطيفة خطأ قدرات التدقيق كذلك.يمكنك استخدامه مثل هذا:

try {
    unsigned int x = lexical_cast<int>("0x0badc0de");
} catch(bad_lexical_cast &) {
    // whatever you want to do...
}

إذا كنت لا تشعر مثل استخدام دفعة ، وهنا نسخة من ضوء المعجمية الزهر الذي لا خطأ التحقق:

template<typename T2, typename T1>
inline T2 lexical_cast(const T1 &in) {
    T2 out;
    std::stringstream ss;
    ss << in;
    ss >> out;
    return out;
}

والتي يمكنك استخدامها مثل هذا:

// though this needs the 0x prefix so it knows it is hex
unsigned int x = lexical_cast<unsigned int>("0xdeadbeef"); 

نصائح أخرى

لطريقة التي تعمل مع كل من C و C ++، قد ترغب في النظر في استخدام strtol القياسية وظيفة مكتبة ().

#include <cstdlib>
#include <iostream>
using namespace std;

int main() {
    string s = "abcd";
    char * p;
    long n = strtol( s.c_str(), & p, 16 );
    if ( * p != 0 ) { //my bad edit was here
        cout << "not a number" << endl;
    }
    else {
        cout << n << endl;
    }
}

واندي بوكانان، بقدر ما تتمسك C ++ يذهب، وأنا أحب لك، ولكن لدي بعض تعديل:

template <typename ElemT>
struct HexTo {
    ElemT value;
    operator ElemT() const {return value;}
    friend std::istream& operator>>(std::istream& in, HexTo& out) {
        in >> std::hex >> out.value;
        return in;
    }
};

والمستخدمة مثل

uint32_t value = boost::lexical_cast<HexTo<uint32_t> >("0x2a");

وبهذه الطريقة لا تحتاج impl واحد لكل نوع int.

وسوف تعمل سبيل المثال مع strtoul تكون:

#include <cstdlib>
#include <iostream>
using namespace std;

int main() { 
    string s = "fffefffe";
    char * p;
    long n = strtoul( s.c_str(), & p, 16 ); 
    if ( * p != 0 ) {  
        cout << "not a number" << endl;
    }    else {  
        cout << n << endl;
    }
}

وstrtol يحول string إلى long. على بلدي numeric_limits<long>::max() الكمبيوتر يعطي 0x7fffffff. من الواضح أن 0xfffefffe أكبر من 0x7fffffff. حتى يعود strtol MAX_LONG بدلا من القيمة المطلوبين. strtoul يحول string إلى unsigned long لهذا السبب لا تجاوز في هذه القضية.

وطيب، strtol تدرس سلسلة الإدخال ليس 32 بت عدد صحيح وقعت قبل convertation. عينة مضحكة مع strtol:

#include <cstdlib>
#include <iostream>
using namespace std;

int main() { 
    string s = "-0x10002";
    char * p;
    long n = strtol( s.c_str(), & p, 16 ); 
    if ( * p != 0 ) {  
        cout << "not a number" << endl;
    }    else {  
        cout << n << endl;
    }
}

ورمز أعلاه يطبع -65538 في وحدة التحكم.

وهنا طريقة بسيطة والعمل وجدت في مكان آخر:

string hexString = "7FF";
int hexNumber;
sscanf(hexString.c_str(), "%x", &hexNumber);

يرجى ملاحظة أنك قد تفضل استخدام غير موقعة طويل عدد صحيح / صحيح طويل، والحصول على قيمة. ملاحظة أخرى، وc_str () وظيفة فقط يحول الأمراض المنقولة جنسيا :: سلسلة لشار CONST *.

وحتى إذا كان لديك شار CONST * جاهز، فقط المضي قدما في استخدام هذا الاسم متغير مباشرة، كما هو مبين أدناه [أنا أيضا تظهر استخدام متغير طويل غير موقعة لعدد عرافة أكبر. لا تخلط بين ذلك مع حالة وجود شار CONST * بدلا من سلسلة]:

const char *hexString = "7FFEA5"; //Just to show the conversion of a bigger hex number
unsigned long hexNumber; //In case your hex number is going to be sufficiently big.
sscanf(hexString, "%x", &hexNumber);

وهذا يعمل فقط تماما على ما يرام (بشرط أن تستخدم أنواع البيانات المناسبة في حاجتك).

وكان لي نفس المشكلة اليوم، وهنا كيف حلها حتى أتمكن من إبقاء lexical_cast <>

typedef unsigned int    uint32;
typedef signed int      int32;

class uint32_from_hex   // For use with boost::lexical_cast
{
    uint32 value;
public:
    operator uint32() const { return value; }
    friend std::istream& operator>>( std::istream& in, uint32_from_hex& outValue )
    {
        in >> std::hex >> outValue.value;
    }
};

class int32_from_hex   // For use with boost::lexical_cast
{
    uint32 value;
public:
    operator int32() const { return static_cast<int32>( value ); }
    friend std::istream& operator>>( std::istream& in, int32_from_hex& outValue )
    {
        in >> std::hex >> outvalue.value;
    }
};

uint32 material0 = lexical_cast<uint32_from_hex>( "0x4ad" );
uint32 material1 = lexical_cast<uint32_from_hex>( "4ad" );
uint32 material2 = lexical_cast<uint32>( "1197" );

int32 materialX = lexical_cast<int32_from_hex>( "0xfffefffe" );
int32 materialY = lexical_cast<int32_from_hex>( "fffefffe" );
// etc...

و(العثور على هذه الصفحة عندما كنت أبحث عن وسيلة أقل مرضية تماما، فيرجى: -)

وابتهاج، A.

وهذا عمل بالنسبة لي:

string string_test = "80123456";
unsigned long x;
signed long val;

std::stringstream ss;
ss << std::hex << string_test;
ss >> x;
// ss >> val;  // if I try this val = 0
val = (signed long)x;  // However, if I cast the unsigned result I get val = 0x80123456 

وطريقة أخرى

using namespace System;

template <typename NUM>
NUM hexstr2num(String^ h)
{
    NUM v=0;
    String^ k=L"0123456789ABCDEF";
    short l=h->Length;
    char off;
    h=h->ToUpper();

    if(h->Substring(0,1)!=L"H")
        {if(h->Substring(0,2)==L"0X") off=2;}
    else
        {off=1;}

    if(!off) throw;

    char dx=0;
    for(int i=l;i>off;i--)
        {
            if((dx=k->IndexOf(h->Substring(i-1,1)))>=0)
                {v+=dx<<((l-i)<<2);}
            else
                {throw;}
        }
    return v;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top