Синтаксис Scanf -% 6d и% -6d и% 0d - PullRequest
       105

Синтаксис Scanf -% 6d и% -6d и% 0d

0 голосов
/ 24 января 2011

В чем разница между использованием scanf со следующими спецификаторами формата, когда сканируемый ввод равен 123456 по сравнению с 123:

  • %6d
  • %-6d
  • %0d

Каковы различия в выходных данных?

Ответы [ 5 ]

5 голосов
/ 24 января 2011

Я просто попробовал GCC 4.3.4 и получил следующее:

  • %6d: отлично работает; читает только 6 символов (поэтому, если вы попытаетесь прочитать 123456789, будет прочитано только 123456)
  • %-6d: выдает предупреждение:

    warning: unknown conversion type character '-' in format
    

    Ничего не читает, а записываемый int неизменен

  • %0d: выдает предупреждение:

    warning: zero width in scanf format
    

    Читается так, как если бы в спецификаторе формата не было ширины (%d)

Я не проверил спецификацию, чтобы увидеть, являются ли эти результаты обязательными или как GCC обрабатывает их ( EDIT : AndreyT нашел его )

5 голосов
/ 24 января 2011

%-6d - это неверный спецификатор формата.Не существует спецификаторов формата с - в них в scanf.

В %6d часть 6 называется максимальная ширина поля .Он работает со всеми спецификаторами формата (не только с d) и определяет максимальное количество символов, которое нужно прочитать перед выполнением любого преобразования, специфичного для формата.Например, если входная последовательность равна 1234567, то %3d будет считывать и преобразовывать 123, а %6d будет считывать и преобразовывать 123456.

%0d является недопустимым спецификатором формата.Максимальная ширина поля в scanf должна быть ненулевым целым числом (см. 7.19.6.2/3 в спецификации языка).

Таким образом, мы оставляем %6d в качестве единственного значимого спецификатора формата средитри вы предоставили.При таких обстоятельствах вопрос о различиях в выходных данных (в результатах?) Не имеет большого смысла.

EDIT: Можно, вероятно, утверждать, что в %-6d часть -6 является максимальным полемширина, которая удовлетворяет стандартному требованию быть ненулевым десятичным целым числом .Однако в терминологии языка Си десятичное целое число как лексический элемент представляет собой последовательность только цифр и цифр.Не разрешается включать знак.Т.е. ни -6, ни +6 не являются десятичными целыми числами.Каждый раз, когда вы используете -6 или +6 в качестве целых чисел в вашей программе, на самом деле это унарный оператор - и +, за которым следует десятичная целая лексема.Таким образом, поскольку для спецификации scanf требуется ненулевое десятичное целое число в качестве максимальной ширины поля, оно должно быть целым числом без знака.

1 голос
/ 24 января 2011

Вот что, я думаю, произойдет:% 6d даст вам первые 6 цифр числа,% -6d, вероятно, не будет работать так, как вы ожидаете, поскольку - это скорее спецификатор выходного выравнивания. % 0d будет означать, что вам нужно только 0 символов, что, вероятно, не будет работать должным образом.

0 голосов
/ 24 января 2011

Я, как и Аркадий, предположу, что вы действительно имели в виду форматирование в стиле printf, поскольку вы ссылаетесь на «выходные данные». Я также предполагаю, что вы используете C (как подсказывает тег).

Если вы запустите:

printf("%6d %-6d %0d", num1, num2);

... вы получите ошибки компилятора (или, что еще хуже, ошибки времени выполнения), поскольку вы не предоставили достаточно аргументов для трех форматов.

У меня такое ощущение, что это не то, о чем вы спрашивали. Давайте предположим, что вы на самом деле запускаете:

// (I've added some extra stuff to show how the formatting works.)
printf("'%6d'/'%-6d'/'%0d'", num2, num2, num2);

... вы получите:

'   123'/'123   '/'123'

Обычно, если ширина поля (в данном случае 6) достаточно широка, числа выровнены по правому краю, дополнены пробелами. Если поставить ширину «-» перед шириной поля, они будут выровнены по правому краю и дополнены пробелами.

Тонкость здесь в формате "% 0d". Вы можете подумать, что вы указываете поле нулевой ширины ... и вы ошибаетесь. Первое, что стоит после «%» - это флаг опции, а «0» - это допустимый флаг. Это означает: «Если ширина поля шире, чем содержимое, то слева от нуля». В этом случае вы не указали ширину поля («0» - это флаг, помните?), Поэтому флаг «0» не имеет никакого эффекта: поле будет настолько широким, насколько этого требует содержимое.

Есть еще худшая тонкость, хотя. Если бы вы указали «% -06d», вы бы получили правильное заполнение нулями, верно? Нет Флаг '-' имеет приоритет над флагом '0', в каком бы порядке они ни указывались. Вы получите «123».

0 голосов
/ 24 января 2011

И %-6d, и %0d являются недопустимыми спецификациями преобразования для scanf, поэтому поведение в этих случаях будет undefined . См. Язык стандарт , & sect; 7.19.6.2, & para; 3.

...