Целое число в шестнадцатеричной строке в С++
Как преобразовать целое число в шестнадцатеричную строку в C++?
Я могу найти несколько способов сделать это, но они, кажется, в основном нацелены на C. Это не кажется естественным способом сделать это в C++. Это довольно простая проблема; У меня есть int
который я хотел бы преобразовать в шестнадцатеричную строку для последующей печати.
Ответы
Ответ 1
Используйте <iomanip>
std::hex
. Если вы печатаете, просто отправьте его в std::cout
, если нет, используйте std::stringstream
std::stringstream stream;
stream << std::hex << your_int;
std::string result( stream.str() );
Вы можете добавить первый <<
с помощью << "0x"
или что угодно, если хотите.
Другими интересами, представляющими интерес, являются std::oct
(восьмеричные) и std::dec
(обратно к десятичной).
Одной из проблем, с которыми вы можете столкнуться, является то, что это дает точное количество цифр, необходимых для его представления. Вы можете использовать setfill
и setw
для обхода проблемы:
stream << std::setfill ('0') << std::setw(sizeof(your_type)*2)
<< std::hex << your_int;
Итак, я бы предложил такую функцию:
template< typename T >
std::string int_to_hex( T i )
{
std::stringstream stream;
stream << "0x"
<< std::setfill ('0') << std::setw(sizeof(T)*2)
<< std::hex << i;
return stream.str();
}
Ответ 2
Чтобы сделать его легче и быстрее, я предлагаю использовать прямое заполнение строки.
template <typename I> std::string n2hexstr(I w, size_t hex_len = sizeof(I)<<1) {
static const char* digits = "0123456789ABCDEF";
std::string rc(hex_len,'0');
for (size_t i=0, j=(hex_len-1)*4 ; i<hex_len; ++i,j-=4)
rc[i] = digits[(w>>j) & 0x0f];
return rc;
}
Ответ 3
Используйте std::stringstream
для преобразования целых чисел в строки и его специальных манипуляторов для установки базы. Например, например:
std::stringstream sstream;
sstream << std::hex << my_integer;
std::string result = sstream.str();
Ответ 4
Просто напечатайте его как шестнадцатеричное число:
int i = /* ... */;
std::cout << std::hex << i;
Ответ 5
Вы можете попробовать следующее. Он работает...
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
template <class T>
string to_string(T t, ios_base & (*f)(ios_base&))
{
ostringstream oss;
oss << f << t;
return oss.str();
}
int main ()
{
cout<<to_string<long>(123456, hex)<<endl;
system("PAUSE");
return 0;
}
Ответ 6
int num = 30;
std::cout << std::hex << num << endl; // This should give you hexa- decimal of 30
Ответ 7
Для тех из вас, кто понял, что многие/большинство ios::fmtflags
не работают с std::stringstream
, но, как идея шаблона, что Kornel отправил назад, когда, работает и является относительно чистым:
#include <iomanip>
#include <sstream>
template< typename T >
std::string hexify(T i)
{
std::stringbuf buf;
std::ostream os(&buf);
os << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2)
<< std::hex << i;
return buf.str().c_str();
}
int someNumber = 314159265;
std::string hexified = hexify< int >(someNumber);
Ответ 8
Просто взгляните на мое решение [1], которое я дословно скопировал из своего проекта, так что в нем есть документация API. Моей целью было объединить гибкость и безопасность с моими фактическими потребностями: [2]
- префикс
0x
не добавлен: звонящий может решить - автоматическое уменьшение ширины: меньше печатать
- явный контроль ширины: расширение для форматирования, (без потерь) сокращение для экономии места
- способен справляться с
long long
- ограничено целочисленными типами: избегайте неожиданностей с помощью тихих преобразований
- простота понимания
- нет жестко заданного ограничения
#include <string>
#include <sstream>
#include <iomanip>
/// Vertextet einen Ganzzahlwert val im Hexadezimalformat.
/// Auf die Minimal-Breite width wird mit führenden Nullen aufgefüllt;
/// falls nicht angegeben, wird diese Breite aus dem Typ des Arguments
/// abgeleitet. Funktion geeignet von char bis long long.
/// Zeiger, Fließkommazahlen u.ä. werden nicht unterstützt, ihre
/// Übergabe führt zu einem (beabsichtigten!) Compilerfehler.
/// Grundlagen aus: /questions/72280/integer-to-hex-string-in-c/486959#486959
template <typename T>
inline std::string int_to_hex(T val, size_t width=sizeof(T)*2)
{
std::stringstream ss;
ss << std::setfill('0') << std::setw(width) << std::hex << (val|0);
return ss.str();
}
[1] основываясь на ответе Корнеля Киселевича
[2] В переводе на язык CppTest это выглядит так:
TEST_ASSERT(int_to_hex(char(0x12)) == "12");
TEST_ASSERT(int_to_hex(short(0x1234)) == "1234");
TEST_ASSERT(int_to_hex(long(0x12345678)) == "12345678");
TEST_ASSERT(int_to_hex((long long)(0x123456789abcdef0)) == "123456789abcdef0");
TEST_ASSERT(int_to_hex(0x123, 1) == "123");
TEST_ASSERT(int_to_hex(0x123, 8) == "00000123");
Ответ 9
Благодаря комментарию Линкольна ниже, я изменил этот ответ.
Следующий ответ правильно обрабатывает 8-битные целые во время компиляции. Это требует, однако, С++ 17. Если у вас нет С++ 17, вам придется сделать что-то еще (например, предоставить перегрузки этой функции, одну для uint8_t и одну для int8_t, или использовать что-то кроме "if constexpr", возможно, enable_if).
template< typename T >
std::string int_to_hex( T i )
{
// Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
std::stringstream stream;
stream << "0x" << std::setfill ('0') << std::setw(sizeof(T)*2) << std::hex;
// If T is an 8-bit integer type (e.g. uint8_t or int8_t) it will be
// treated as an ASCII code, giving the wrong result. So we use C++17's
// "if constexpr" to have the compiler decides at compile-time if it
// converting an 8-bit int or not.
if constexpr (std::is_same_v<std::uint8_t, T>)
{
// Unsigned 8-bit unsigned int type. Cast to int (thanks Lincoln) to
// avoid ASCII code interpretation of the int. The number of hex digits
// in the returned string will still be two, which is correct for 8 bits,
// because of the 'sizeof(T)' above.
stream << static_cast<int>(i);
}
else if (std::is_same_v<std::int8_t, T>)
{
// For 8-bit signed int, same as above, except we must first cast to unsigned
// int, because values above 127d (0x7f) in the int will cause further issues.
// if we cast directly to int.
stream << static_cast<int>(static_cast<uint8_t>(i));
}
else
{
// No cast needed for ints wider than 8 bits.
stream << i;
}
return stream.str();
}
Оригинальный ответ, который не обрабатывает 8-битные целочисленные значения правильно, как я думал, что сделал:
Корнел Киселевич отвечает отлично. Но небольшое добавление помогает поймать случаи, когда вы вызываете эту функцию с аргументами шаблона, которые не имеют смысла (например, с плавающей точкой) или могут привести к ошибкам компилятора (например, определяемый пользователем тип).
template< typename T >
std::string int_to_hex( T i )
{
// Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
std::stringstream stream;
stream << "0x"
<< std::setfill ('0') << std::setw(sizeof(T)*2)
<< std::hex << i;
// Optional: replace above line with this to handle 8-bit integers.
// << std::hex << std::to_string(i);
return stream.str();
}
Я отредактировал это, чтобы добавить вызов std :: to_string, потому что 8-битные целочисленные типы (например, std::uint8_t
значения std::uint8_t
) в std::stringstream
обрабатываются как char, что не дает желаемого результата. Передача таких целых чисел в std::to_string
обрабатывает их правильно и не причиняет вреда при использовании других, более крупных целочисленных типов. Конечно, вы можете столкнуться с небольшим падением производительности в этих случаях, так как вызов std :: to_string не нужен.
Примечание: я бы просто добавил это в комментарии к первоначальному ответу, но у меня нет представителя, чтобы комментировать.
Ответ 10
Этот вопрос старый, но я удивлен, почему никто не упомянул boost::format
:
cout << (boost::format("%x") % 1234).str(); // output is: 4d2
Ответ 11
Код для справки:
#include <iomanip>
...
string intToHexString(int intValue) {
string hexStr;
/// integer value to hex-string
std::stringstream sstream;
sstream << "0x"
<< std::setfill ('0') << std::setw(2)
<< std::hex << (int)intValue;
hexStr= sstream.str();
sstream.clear(); //clears out the stream-string
return hexStr;
}
Ответ 12
Я делаю:
int hex = 10;
std::string hexstring = stringFormat("%X", hex);
Посмотрите на fooobar.com/questions/8459/... ответ от iFreilicht и требуемый заголовочный файл шаблона отсюда GIST !
Ответ 13
'
char sw(int num){
char h[16] = {'0','1','2','3','4','5','6','7','8','9','a','b',' c','d','e','f'};
return h[num];
}
String to_hexa(int num) {
int i, j, exp = 0, temp = num;
String hexa;
String begin;
while( temp >= 16 ){
exp++;
temp /= 16;
}
for ( i = 0; i <= exp; ++i){
temp = num;
for ( j = i; j <= exp; ++j){
if ( j == exp ) hexa += String(sw(temp % 16));
else temp /= 16;
}
}
begin = "0x";
for (int i=0; i < 3 - exp; i++){
begin += "0";
}
return begin + hexa;
}
'
Ответ 14
int var = 20;
cout << &var << endl;
cout << (int)&var << endl;
cout << std::hex << "0x" << (int)&var << endl << std::dec; // output in hex, reset back to dec
0x69fec4 (адрес)
6946500 (адрес до декабря)
0x69fec4 (адрес в декабрь, вывод в шестнадцатеричном формате)
инстинктивно пошел с этим...
int address = (int) & var;
видел это в другом месте...
длинный адрес без знака = reinterpret_cast (& var);
комментарий сказал мне, что это правильно...
int address = (int) & var;
Ответ 15
Попробуй это:
#include<iostream>
using namespace std;
int main() {
int *a = new int;//or put a number exept new int
//use * for pointer
cin >> *a;
cout << a; //if integer that is made as pointer printed without *, than it will print hex value
return 0;
//I hope i help you
}