Он не понимает ваш код; это кажется слишком сложным. Но один
Конечно, если вы конвертируете внутреннее представление в
восьмерично, вам нужно где-то разделить на 8 и сделать % 8
где-то. И я их не вижу. С другой стороны, я вижу оба
операции с 10 и 1000, ни одна из которых не должна присутствовать.
Для начала, вы можете написать простую функцию, которая преобразует
значение (предпочтительно unsigned
некоторого типа & mdash; получить unsigned
прямо перед тем, как беспокоиться о знаке) на строку, используя любую базу, например ::
//! \pre
//! base >= 2 && base < 36
//!
//! Digits are 0-9, then A-Z.
std::string convert(unsigned value, unsigned base);
Это не должно занимать более 5 или 6 строк кода. Но внимание,
нормальный алгоритм генерирует цифры в обратном порядке: если вы
используя std::string
, самое простое решение - push_back
каждая цифра,
затем позвоните std::reverse
в конце, прежде чем вернуть его. В противном случае:
Стиль C char[]
работает хорошо, если вы сделаете его достаточно большим.
(sizeof(unsigned) * CHAR_BITS + 2
более чем достаточно, даже для
подписанный, и даже с '\0'
в конце, который вам не понадобится, если вы
верните строку.) Просто инициализируйте указатель на buffer +
sizeof(buffer)
и выполняйте предварительное уменьшение при каждом добавлении цифры. к
создайте возвращаемую строку:
std::string( pointer, buffer + sizeof(buffer) )
должен сделать трюк.
Что касается цикла, конечное условие может быть просто value == 0
.
(Вы будете делить value
на base
каждый раз, так что вы
гарантированно достигнет этого условия.) Если вы используете do ... while
,
вместо while
, вам также гарантируется как минимум одна цифра
выход.
(Мне было бы намного проще просто опубликовать код, но так как
это, очевидно, домашнее задание, я думаю, что лучше просто дать показания
относительно того, что должно быть сделано.)
Редактировать: Я добавил свою реализацию и некоторые комментарии к вашей новой
код:
Сначала для комментариев: очень вводящее в заблуждение приглашение: «Введите
двоичное число "звучит так, как будто пользователь должен ввести двоичное; если вы
при чтении в int
вводимое значение должно быть десятичным. И здесь
все еще % 1000
и / 1000
и % 10
и / 10
, которые я не делаю
Понимаю. Что бы вы ни делали, это не может быть правильным, если нет %
8
и / 8
. Попробуйте: введите "128"
, например, и посмотрите, что вы получите.
Если вы пытаетесь ввести двоичный файл, то вам действительно нужно ввести
строка и разбери сам.
Мой код для самого преобразования:
//! \pre
//! base >= 2 && base <= 36
//!
//! Digits are 0-9, then A-Z.
std::string toString( unsigned value, unsigned base )
{
assert( base >= 2 && base <= 36 );
static char const digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buffer[sizeof(unsigned) * CHAR_BIT];
char* dst = buffer + sizeof(buffer);
do
{
*--dst = digits[value % base];
value /= base;
} while (value != 0);
return std::string(dst, buffer + sizeof(buffer));
}
Если вы хотите проанализировать ввод (например, для двоичного файла), то что-то вроде
следующие должны сделать трюк:
unsigned fromString( std::string const& value, unsigned base )
{
assert( base >= 2 && base <= 36 );
static char const digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
unsigned results = 0;
for (std::string::const_iterator iter = value.begin();
iter != value.end();
++ iter)
{
unsigned digit = std::find
( digits, digits + sizeof(digits) - 1,
toupper(static_cast<unsigned char>( *iter ) ) ) - digits;
if ( digit >= base )
throw std::runtime_error( "Illegal character" );
if ( results >= UINT_MAX / base
&& (results > UINT_MAX / base || digit > UINT_MAX % base) )
throw std::runtime_error( "Overflow" );
results = base * results + digit;
}
return results;
}
Это сложнее, чем toString
, потому что он должен обрабатывать все виды
возможных состояний ошибки. Это также все еще, вероятно, проще, чем вы
необходимость; Вы, вероятно, хотите обрезать заготовки и т. д., а также (или даже игнорировать
их: ввод 01000000
более подвержен ошибкам, чем 0100 0000
).
(Кроме того, конечный итератор для find
имеет - 1
из-за трейлинга
'\0'
компилятор вставляет в digits
.)