Спецификатор формата в C ++ - PullRequest
0 голосов
/ 03 февраля 2020

Я пытаюсь понять поведение компилятора C ++. Вот код, в котором я умышленно сделал две ошибки:

  1. забыл %ld спецификатор формата в scanf и только что написал %.
  2. добавил неизвестный спецификатор формата для printf - написал %l вместо %ld для long тип данных.
#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    // Complete the code.
    int a; long b; char c; float d; double e;
    scanf("%d % %c %f %lf", &a, &b, &c, &d, &e);
    printf("%d \n%l \n%c \n%f \n%lf", a, b, c, d, e);
    return 0;
}

Выше приведен фрагмент кода, который успешно компилирует и показывает предупреждения. Почему он не выдал ошибку для неизвестного / отсутствующего спецификатора формата C ++? Как это было скомпилировано?

Вывод: Input data and strange output after mistakes

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

Компилятор не обязан даже говорить вам об этом (будьте благодарны!). Несоответствие между строкой формата и списком аргументов является неопределенным поведением.

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

0 голосов
/ 03 февраля 2020

Потому что % - это не неизвестный спецификатор формата, а только это - знак процента, за которым следует (один или несколько) пробел. В вашем входном потоке выполняется поиск знака процента, и если ни один из них не отображается должным образом, он прекращает сопоставление и возвращает число уже назначенных полей - одно.

Очевидно, что это редко, что намерено кодировщиками, поэтому компилятор выдает предупреждение об этом. Чтобы более четко заявить, что вы хотите получить реальный знак процента, можно использовать %%. Процент и пустые запахи для компилятора, как если бы вы допустили ошибку, но это не является формально неправильным; поэтому это только предупреждение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...