ostream showbase не показывает "0x" для нулевого значения - PullRequest
10 голосов
/ 18 июля 2010

PSPS: (Предварительный сценарий пост-сценария)
Только что пришло в голову, что более предусмотрительный вопрос включал бы понятие: не является ли это показом "0x"(showbase) для целых чисел с нулевым значением стандартное поведение, или это просто причуды моей реализации MinGW?

Все началось приятным воскресным утром ... Я хочу вывести некоторые дескрипторы в их шестнадцатеричное представление и в последовательном, отформатированном виде.
Я хочу ведущий 0x и фиксированная ширина , но это оказывается труднодостижимым с использованием ожидаемых потоковых манипуляторов.
Единственный способ, которым я нашел это, состоит в том, чтобы привести Handles кбез знака долго.Это кажется немного неразумным, и я ожидаю, что я не единственный человек, который когда-либо хотел этого ..
Я что-то упускаю в стандартных шестнадцатеричных манипуляторах?Это потому, что тип void * (HANDLE) просто определен вне обычной шестнадцатеричной обработки ostream?

В итоге: Я не хочу приводить HANDLE к чему-то, что не является.
и я не хочу жестко кодировать префикс "0x",Есть ли способ сделать это с помощью стандартных манипуляторов?или мне нужно было бы перегружать обработку HANDLE ostream?(но это может перегрузить меня!)

Вот мой тестовый код (и его вывод).
Я использовал '.'в качестве заливки, для ясности (на самом деле я буду использовать '0')

HANDLE h; 
ULONG ul; 
int iH = sizeof(h); // how many bytes to this void* type.
int iW = iH*2;      // the max number of hex digits (width).
int iW2= iW+2;      // the max number of hex digits (+ 2 for showbase "0x").
int iX = 4;         // the number of bits per hex digit.
int ib = iH*8;      // the max number bits in HANDLE (exponent).
int i;
std::cout<<std::setfill('.'); // I actually want '0'; 
                              //   the dot is for display clarity
for( i=0; i<=ib; i+=iX )
{ ul = (pow(2,i)-1);
  h  = (HANDLE)ul;
  std::cout
  <<"//  ul "        <<std::setw(iW2)<<std::hex <<std::showbase  <<std::internal <<ul
  <<"     h "        <<std::setw(iW2) /* hex,showbase,internal have no effect */ <<h
  <<"      I want 0x"<<std::setw(iW) <<std::hex <<std::noshowbase<<std::right    <<(ULONG)h
  <<std::endl;
}

//  ul .........0     h .........0      I want 0x.......0
//  ul 0x.......f     h .......0xf      I want 0x.......f
//  ul 0x......ff     h ......0xff      I want 0x......ff
//  ul 0x.....fff     h .....0xfff      I want 0x.....fff
//  ul 0x....ffff     h ....0xffff      I want 0x....ffff
//  ul 0x...fffff     h ...0xfffff      I want 0x...fffff
//  ul 0x..ffffff     h ..0xffffff      I want 0x..ffffff
//  ul 0x.fffffff     h .0xfffffff      I want 0x.fffffff
//  ul 0xffffffff     h 0xffffffff      I want 0xffffffff

Ответы [ 2 ]

11 голосов
/ 18 июля 2010

Я нашел это на https://bugzilla.redhat.com/show_bug.cgi?id=166735 - это копирование / вставка прямо оттуда.

Не похоже на ошибку для меня.ISO C ++ 98, 22.2.2.2.2 / 10 говорит, что std :: showbase означает добавление префикса преобразования # printf.22.2.2.2.2 / 7 говорит, что std :: hex означает, что спецификатор преобразования printf равен% x.Таким образом, поведение IMHO должно быть таким же, как printf ("% # x", 0);Но http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html говорит: «Для спецификаторов преобразования x или X ненулевой результат должен иметь префикс 0x (или 0X)».То же самое в ISO C99, 7.19.6.1 (6): «Для преобразования x (или X) ненулевой результат имеет префикс 0x (или 0X)».

Так что это звучит какстандарт C ++ 98 (говорящий «сделайте его похожим на printf C («% # x », 0)») требует такого глупого поведения, которое вы видите.Единственный способ получить то, что вы хотите - это избавиться от std :: showbase и явно вывести 0x.К сожалению.

6 голосов
/ 02 августа 2010

Тот факт, что std :: showbase не имеет "0x", когда значение равно нулю, иногда раздражает, но это то, как оно определено, и с этим ничего не поделаешь, кроме:

std::cout << "0x" << .....

Разрыв между "0x" и остальными можно исправить, но это не очень легко догадаться. Попробуйте

std::cout << std::hex << std::showbase << std::setw(8) << std::setfill('0') << h;
...