Вывести десятичные версии неизвестного ввода - PullRequest
0 голосов
/ 31 января 2019

Я пытаюсь написать короткий скрипт, который будет принимать 6 входных данных в десятичном, шестнадцатеричном или восьмеричном виде и выводить их десятичные версии.Например, если я введу 1, 1 должен быть выведен.Вход 010, должен получить 8, вход 0x20, должен получить 32. Нужно ли проверять каждое значение, чтобы увидеть, читает ли scanf его как его тип, или я могу привести их после того, как scanf прочитает их все как есть?Также мне нужны функции для преобразования восьмеричных и шестнадцатеричных значений в десятичные или я могу привести их?Я очень плохо знаком с C и пока не очень хорошо понимаю, но вот что у меня есть (по каким-либо причинам он выдает -200 как 32765):

    int num[6];
    printf("Enter six integers:\n");

    int i = 0;
    int j;
    while (i < 6){
            if(scanf("0x%x", &j) == 1){
                    scanf("0x%x", &num[i]);
                    //hexToDec(num[i]);
            } else if (scanf("0%o", &j) == 1){
                    scanf("0%o", &num[i]);
                    //octalToDec(num[i]);
            } else {
                     scanf("%i", &num[i]);
            }
            i+=1;
    }

    for(int p = 0; p < 6; p+=1){
            printf("%i\n", num[p]);
    }

Ответы [ 4 ]

0 голосов
/ 31 января 2019

Быстрый ответ - использовать только

if(scanf("%i", &j) == 1){
  ...
}

что у меня есть (выводит -200 как 32765 по любой причине):

И все же обработка ошибок scanf() проблематична.Гораздо лучше прочитать строку ввода пользователя с помощью fgets(), а затем проанализировать строку - возможно, с помощью strtol().

0 голосов
/ 31 января 2019

Ответ для дальнейшего использования: простое сканирование с использованием "% i" выполняет преобразования автоматически.Пересмотренный код ниже:

int main(){

    int num[6];
    printf("Enter six integers:\n");

    int i = 0;
    while (i < 6){
            scanf("%i", &num[i]);
            i+=1;
    }

    for(int p = 0; p < 6; p+=1){
            printf("%i\n", num[p]);
    }

}

0 голосов
/ 31 января 2019

Вы можете использовать функцию strtol с базой 0 для автоматического определения базы интегральных значений в соответствии с форматом входных строк (см., Например, документацию strtol в cppreference.com):

long strtol (const char * str, char ** str_end, int base)

Интерпретирует целочисленное значение в байтовой строке, указывающей напо ул.... Допустимое целочисленное значение состоит из следующих частей:

  • (необязательно), знак плюс или минус
  • (необязательно) префикс (0), указывающий восьмеричное основание (применяется только в том случае, еслиоснование равно 8 или 0)
  • (необязательно) префикс (0x или 0X), указывающий шестнадцатеричное основание (применяется только, когда основание равно 16 или 0)

Еслизначение базы равно 0, числовая база определяется автоматически.

Таким образом, вызов типа long val = strtol("0x10",NULL,0); даст десятичное значение 16.

Обратите внимание, что вы можететакже используйте scanf в сочетании со спецификатором формата %i, поскольку он определен так, чтобы вести себя так же, как вызов strtol:

int scanf(const char * format, ...)

% i соответствует целому числу.Формат числа такой же, как и ожидалось strtol () со значением 0 для базового аргумента (база определяется по первым проанализированным символам)

0 голосов
/ 31 января 2019

Вы не можете использовать scanf("0x%x", &j) для проверки ввода, а затем использовать scanf("0x%x", &num[i]), чтобы ввести значение в num[i].scanf потребляет символов, которые он принимает, поэтому их больше нет во входном потоке.Когда вы делаете второй scanf, символы исчезают.

Вместо этого просто попробуйте отсканировать нужную вещь.Если это работает, вы сделали.Если это не работает, перейдите к else:

if (scanf("0x%x", &num[i]) == 1)
    ; // Worked, nothing to do.
else if (scanf("0%o", &num[i]) == 1)
    ;
else if (scanf("%i", &num[i]) == 1)
    ;
else
{
    // Nothing worked, should put error-handling code here.
}

Это на самом деле не очень хороший код для реальных приложений, потому что scanf будет потреблять часть входных данных, даже если в конечном итоге произойдет сбой.Например, при scanf("0x%x", &num[i]), если вход содержит «0x», но содержит не шестнадцатеричный символ, scanf будет использовать «0x», но оставит следующий символ.Тем не менее, этого достаточно для обучения.

Если у вас есть значения в массиве num, они являются просто int значениями.Это математические значения, а не цифры в восьмеричном, десятичном или шестнадцатеричном формате.Вы можете напечатать их с %o для восьмеричного или %d или %i для десятичного.Оригинальная цифра не имеет значения.При печати математическое значение будет использоваться для форматирования строки в запрошенной базе.

Не следует использовать %x для печати int, так как %x для unsigned int.Однако вы можете преобразовать int в unsigned int и затем распечатать его с %x.

Обратите внимание, что вам не следует сканировать объекты с int с %x.%x - для сканирования на unsigned int объектов.На самом деле вы можете сканировать шестнадцатеричные, восьмеричные и десятичные числа, используя:

if (scanf("%i", &num[i]) == 1)
    ;
else
    …

Спецификация %i распознает шестнадцатеричные цифры, начинающиеся с «0x», восьмеричные цифры, начинающиеся с «0», и десятичные цифры.

Если вы не хотите использовать %i для всех трех, потому что по какой-то причине вам нужен прямой контроль, вам нужно будет написать больше кода.Стандарт C не обеспечивает прямой способ сканирования только шестнадцатеричного числа в int.Вам нужно будет получить символы из входных данных и вычислить их значение или отсканировать до unsigned int, а затем преобразовать результат в int.

...