Как использовать спецификатор ширины scanf 0?

как использовать спецификатор ширины scanf 0?
1) неограниченная ширина (как видно из cywin GCC версии 4.5.3)
2) УБ
3) что-то еще?

мое приложение (не показано) динамически формирует спецификатор ширины как часть строки большего формата для scanf (). Редко это создаст "%0s" в середине строки формата. В этом контексте строка назначения для этого %0s имеет только 1 байт места для scanf() в магазине что с поведение №1 выше вызывает проблемы.

Примечание: В следующих тестовых случаях используются постоянные форматы.

#include <memory.h>
#include <stdio.h>

void scanf_test(const char *Src, const char *Format) {
  char Dest[10];
  int NumFields;
  memset(Dest, '', sizeof(Dest)-1);
  NumFields = sscanf(Src, Format, Dest);
  printf("scanf:%d Src:'%s' Format:'%s' Dest:'%s'n", NumFields, Src, Format, Dest);
}

int main(int argc, char *argv[]) {
  scanf_test("1234" , "%s");
  scanf_test("1234" , "%2s");
  scanf_test("1234" , "%1s");
  scanf_test("1234" , "%0s");
  return 0;
}

выход:

scanf:1 Src:'1234' Format:'%s' Dest:'1234'  
scanf:1 Src:'1234' Format:'%2s' Dest:'12'  
scanf:1 Src:'1234' Format:'%1s' Dest:'1'  
scanf:1 Src:'1234' Format:'%0s' Dest:'1234' 

мой вопрос о последней строке. Кажется, что ширина 0 не приводит к ограничению ширины, а не к ширине 0. Если это правильное поведение или UB, мне придется подойти к ситуации нулевой ширины другим способом или есть другие форматы scanf() для рассмотрения?

2 ответов


спецификатор максимальной ширины поля должен быть ненулевым. C99, 7.19.6.2:

формат должен быть многобайтовой символьной последовательностью, начинающейся и заканчивающейся в начальной состояние сдвига. Формат состоит из нуля или нескольких директив: одного или нескольких пробелов символы, обычный многобайтовый символ (ни % или пробел), или спецификация преобразования. Каждая спецификация преобразования вводится символом %. После %, следующие появляются в последовательности:
- Необязательное назначение-подавление символа *.
- необязательное ненулевое десятичное целое число, указывающее максимальную ширину поля (в письмена.)
- Необязательный длина модификатор указывает размер принимающего объекта.
- А спецификатор преобразования символ, указывающий тип применяемого преобразования.

так, если вы используете 0, поведение не определено.


Это произошло из 7.21.6.2 из n1570.pdf (проект стандарта C11):

после % последовательно появляется следующее:

- необязательный символ подавления назначения *.

- необязательное десятичное целое число больше нуля, что указывает максимальная ширина поля (в символах).

...

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

пункт ввода определяется как самая длинная последовательность входных символов которая не превышает заданной ширины поля И...

чего вы хотите достичь, прочитав поле ширины 0 и назначив его как строку (пустую строку) в Dest? Какую проблему вы пытаетесь решить? Кажется более ясным просто назначить как *Dest = '';.