Может ли `std :: istream :: operator >> ()` принимать целочисленные префиксы radix, такие как спецификатор формата stdio% i? - PullRequest
10 голосов
/ 18 декабря 2010

При использовании scanf () и его вариантов спецификатор формата %i будет принимать данные как шестнадцатеричные (с префиксом «0x»), восьмеричные (с префиксом «0») или десятичные (без префикса), например, строки «0x10», «020» и «16» преобразуются в целое число с десятичным значением 16.

Можно ли это сделать с помощью std::istream::operator>> отформатированного ввода?

При использовании обычного >> i без манипулятора ввода / вывода "0x10" преобразуется в ноль (или, скорее, ведущий 0 - часть "x10" не обрабатывается), а "020" - в 20. hex Манипуляторы oct и dec ведут себя как %x, %o и %d соответственно. Я ищу общий целочисленный манипулятор ввода, который работает как %i.

Интересно, что, возможно, манипулятор hex принимает как "0x10", так и "10", преобразуя либо в 16 десятичное число.

Если вам может быть интересно, я реализую оценщик выражений, и я бы хотел, чтобы разрешенные целочисленные операнды были шестнадцатеричными, восьмеричными или десятичными, используя соглашение префиксов C / C ++. Текущая реализация, использующая sscanf(), делает это автоматически, используя %i, и мне любопытно, можно ли изменить это для использования iostream без необходимости явного разбора числового формата.

Ответы [ 2 ]

10 голосов
/ 18 декабря 2010

Базовое поле в флагах формата basic_istream определяет способ интерпретации чисел.Поле может быть установлено на dec, oct и hex.По умолчанию установлено значение dec.Если для него не задано ни одного из них, basic_istream будет вести себя как scanf 's %i флаг:

// automatically detect the base, depending on prefix
std::cin.unsetf(std::ios_base::basefield);
1 голос
/ 03 августа 2018

Вместо прямого сброса базового поля, немного более интуитивно решение заключается в использовании манипулятора setbase(int base):

#include <iomanip>
#include <iostream>

int main()
{
  int i;
  std::cin >> std::setbase(0) >> i;
  std::cout << i << std::endl;
}

Процитировать cppreference:

Значения базы, отличные от 8, 10 или 16, сбрасывают базовое поле на ноль, что соответствует десятичному выходу и префиксно-зависимому вводу.

...