Chcę przekonwertować ciąg szesnastkowy na 32-bitową liczbę całkowitą ze znakiem w C ++.
Na przykład mam ciąg szesnastkowy „fffefffe”. Binarna reprezentacja tego to 11111111111111101111111111111110. Reprezentacja liczb całkowitych ze znakiem to: -65538.
Jak wykonać tę konwersję w C ++? To również musi działać dla liczb nieujemnych. Na przykład ciąg szesnastkowy „0000000A”, czyli 00000000000000000000000000001010 w systemie dwójkowym i 10 w systemie dziesiętnym.
int
. „32-bitowa liczba całkowita ze znakiem” może mieć postać int32_t lub __int32 itd.Odpowiedzi:
posługiwać się
std::stringstream
następujący przykład daje
-65538
wynik:W nowym standardzie C ++ 11 jest kilka nowych funkcji narzędziowych, z których możesz skorzystać! w szczególności istnieje rodzina funkcji „ciąg do numeru” ( http://en.cppreference.com/w/cpp/string/basic_string/stol i http://en.cppreference.com/w/cpp/string/ basic_string / stoul ). Są to zasadniczo cienkie opakowania wokół funkcji konwersji ciągów na liczby w języku C, ale wiedzą, jak sobie radzić z
std::string
Tak więc najprostsza odpowiedź na nowszy kod prawdopodobnie wyglądałaby następująco:
UWAGA: Poniżej znajduje się moja oryginalna odpowiedź, która zgodnie z edycją nie jest odpowiedzią pełną. Aby uzyskać funkcjonalne rozwiązanie, umieść kod powyżej linii :-).
Wydaje się, że ponieważ
lexical_cast<>
jest zdefiniowany jako semantyka konwersji strumienia. Niestety, strumienie nie rozumieją notacji „0x”. Więc zarówno ta, jakboost::lexical_cast
i moja wyrzucona ręka nie radzą sobie dobrze z ciągami hex. Powyższe rozwiązanie, które ręcznie ustawia strumień wejściowy na hex, poradzi sobie z tym dobrze.Boost ma też kilka rzeczy do zrobienia, które ma również niezłe możliwości sprawdzania błędów. Możesz go używać w ten sposób:
Jeśli nie masz ochoty korzystać z funkcji Boost, oto lekka wersja rzutowania leksykalnego, która nie sprawdza błędów:
którego możesz użyć w ten sposób:
źródło
std::hex
stringstream
S należy sprawdzićss.good() && ss.eof()
, aby upewnić się, że nie wystąpiły żadne błędy.W przypadku metody, która działa zarówno z C, jak i C ++, warto rozważyć użycie funkcji biblioteki standardowej strtol ().
źródło
strtoul
niestrtol
. Będzie+ overflow
podczas używania strtol. Dzięki temustrtoul
nie będzie przepełnienia, a zwrócona wartość zostanie przekonwertowana nalong
poprawny wynik (-65538). Więc twoja odpowiedź prawie poprawna :)Andy Buchanan, jeśli chodzi o trzymanie się C ++, podobał mi się twój, ale mam kilka modów:
Używane jak
W ten sposób nie potrzebujesz jednego elementu impl na typ int.
źródło
Przykład roboczy z
strtoul
będzie:strtol
konwertujestring
dolong
. Na moim komputerzenumeric_limits<long>::max()
daje0x7fffffff
. Oczywiście to0xfffefffe
jest większe niż0x7fffffff
. Więcstrtol
zwracaMAX_LONG
zamiast pożądanej wartości.strtoul
konwertujestring
dounsigned long
to, dlaczego w tym przypadku nie ma przepełnienia.Ok,
strtol
rozważa wejściowy ciąg znaków nie jako 32-bitową liczbę całkowitą ze znakiem przed konwersją. Zabawna próbka zawierającastrtol
:Powyższy kod jest drukowany
-65538
w konsoli.źródło
Oto prosta i działająca metoda, którą znalazłem gdzie indziej:
Pamiętaj, że możesz preferować użycie długiej liczby całkowitej bez znaku / długiej liczby całkowitej do otrzymania wartości. Inna uwaga, funkcja c_str () po prostu konwertuje std :: string na const char *.
Więc jeśli masz gotową const char *, po prostu użyj bezpośrednio tej nazwy zmiennej, jak pokazano poniżej [Pokazuję również użycie długiej zmiennej bez znaku dla większej liczby szesnastkowej. Nie myl tego z przypadkiem posiadania const char * zamiast string]:
Działa to doskonale (pod warunkiem, że używasz odpowiednich typów danych zgodnie z potrzebami).
źródło
Miałem dzisiaj ten sam problem, oto jak go rozwiązałem, aby zachować lexical_cast <>
(Znalazłem tę stronę, gdy szukałem mniej pechowego sposobu :-)
Pozdrawiam, A.
źródło
To zadziałało dla mnie:
źródło
Spróbuj tego. Takie rozwiązanie jest nieco ryzykowne. Nie ma czeków. Ciąg musi mieć tylko wartości szesnastkowe, a długość ciągu musi odpowiadać rozmiarowi zwracanego typu. Ale nie ma potrzeby stosowania dodatkowych nagłówków.
Stosowanie:
Uwaga: długość łańcucha musi być podzielna przez 2
źródło