Почему эта программа не печатает желаемый результат?

Я просто знаю о спецификаторе формата% i из этой ссылки

Разница между спецификаторами формата% i и% d в printf

и я попытался реализовать это с помощью этой программы.

#include <stdio.h>

int main(){

    long long a,b;

    printf("Input: ");

    scanf("%i %lld",&b,&a);

    printf("Output: %i %lld",b,a);
}

% i работал правильно, но% lld сохраняет значение мусора в переменной a.

Это результат работы этой программы.

Ввод: 033 033

Выход: 27 141733920846

Процесс вернул 0 (0x0). Время выполнения: 4,443 с. Для продолжения нажмите любую клавишу.

Может ли кто-нибудь объяснить, почему я получаю значение мусора в переменной a?


person Mayur Kharche    schedule 24.06.2016    source источник
comment
вы не ввели% 11d, вы ввели 033 \ n (и немного мусора из предыдущих выполнений), которые были интерпретированы scanf, ошибкой здесь является форматирование в scanf и сам scanf.   -  person Gar    schedule 24.06.2016
comment
Передача недопустимых вещей в scanf является неопределенным поведением, а% lld не принимает восьмеричные литералы.   -  person magisch    schedule 24.06.2016
comment
Возможный дубликат Неверный спецификатор формата в scanf (или) printf   -  person phuclv    schedule 24.06.2016
comment
Использование неправильного спецификатора формата вызывает неопределенное поведение stackoverflow.com/q/4231891/995714, stackoverflow.com/q/16864552/995714   -  person phuclv    schedule 24.06.2016


Ответы (2)


scanf %i принимает int *, но вы проходите &b, что является long long int *. Это имеет неопределенное поведение.

Вы должны использовать %lli.

Та же проблема возникает в printf: используйте %lli для печати b, а не %i.

Вы также должны проверить возвращаемое значение scanf, чтобы убедиться, что два значения были успешно прочитаны.

person melpomene    schedule 24.06.2016
comment
Да, я тоже забыл исправить это в printf. Я обновил свой ответ, добавив исправленный код и живую демонстрацию. - person magisch; 24.06.2016

Прежде всего, использование %i для long long int является неопределенным поведением, поэтому используйте вместо этого %lli.

Та же проблема сохраняется и в инструкции printf.

Фиксированный код:

#include <stdio.h>


int main(){

    long long a,b;
    int retval;


    printf("Input: \n");

    retval = scanf("%lli %lld",&b,&a);

    printf("Output: %lli %lld",b,a);
    printf("\nRetval: %d",retval);
    return 1;
}

Вход:

033 033

Вывод:

Вход: Выход: 27 33 Возврат: 2

Живая демонстрация

Примечание. Всегда проверяйте возвращаемое значение scanf. Он возвращает количество отсканированных элементов, которые вы должны проверить на соответствие вашим ожиданиям.

person magisch    schedule 24.06.2016
comment
Я почти уверен, что %d должен читать "033" как 33, например, atoi("033"). - person melpomene; 24.06.2016
comment
@melpomene Можете ли вы предоставить для этого источник? Я почти уверен, что это неверный ввод. - person magisch; 24.06.2016
comment
port70.net/~nsz/c/c99/n1256.html # 7.19.6.2p12 говорит, что %d работает как strtol(..., 10). port70.net/~nsz/c/c99/n1256.html# 7.20.1.4 говорит, что допустимы цифры, меньшие, чем основание (т. Е. 0 .. 9). Он не запрещает начальные нули. - person melpomene; 24.06.2016
comment
@melpomene Тогда я поправлюсь. Интересно, что изменение только на% lli не приведет к исчезновению значения мусора. в настоящее время ведется дальнейшее расследование этого вопроса. - person magisch; 24.06.2016