Является ли регулярность в регулярном выражении scanf? - PullRequest
18 голосов
/ 14 мая 2011

Является ли регулярность в регулярном выражении scanf? Я нигде не могу найти ответ.

Этот код работает в gcc, но не в Visual Studio:

scanf("%[^\n]",a);

Это ошибка Visual Studio или расширение gcc?

РЕДАКТИРОВАТЬ: похоже, VS работает, но нужно учитывать разницу в концах строк между Linux и Windows. (\ R \ n)

Ответы [ 2 ]

8 голосов
/ 14 мая 2011

Эта конкретная строка формата должна нормально работать в соответствующей реализации.Символ [ вводит набор сканирования для сопоставления непустого набора символов (с ^ означает, что набор сканирования является инверсией предоставленных символов).Другими словами, спецификатор формата %[^\n] должен соответствовать каждому символу, который не является новой строкой.

С C99 7.19.6.2, слегка перефразируя:

Спецификатор формата [ соответствуетнепустая последовательность символов из набора ожидаемых символов (скансет).Если модификатор длины l отсутствует, соответствующий аргумент должен быть указателем на начальный элемент массива символов, достаточно большой, чтобы принять последовательность, и завершающий нулевой символ, который будет добавлен автоматически.

Еслиприсутствует модификатор длины l, входные данные должны быть последовательностью многобайтовых символов, которая начинается в начальном состоянии сдвига.Каждый многобайтовый символ преобразуется в широкий символ, как если бы он вызывался функцией mbrtowc, причем состояние преобразования описывается объектом mbstate_t, инициализированным в ноль перед преобразованием первого многобайтового символа.Соответствующим аргументом должен быть указатель на начальный элемент массива wchar_t, достаточно большой, чтобы принять последовательность и завершающий нулевой широкий символ, который будет добавлен автоматически.

Спецификатор преобразования включает в себя все последующие символыв строке формата, вплоть до соответствующей правой скобки ].Символы в скобках (список сканирования) составляют набор сканирования, если символ после левой скобки не является окружностью ^, и в этом случае набор содержит все символы, которые не появляются в списке сканирования между кольцом и правой скобкой.Если спецификатор преобразования начинается с [] или [^], правый символ скобки находится в списке сканирования, а следующий следующий правый символ скобки - это совпадающая правая скобка, которая завершает спецификацию;в противном случае первый следующий символ правой скобки - это тот, который завершает спецификацию.Если символ - находится в списке сканирования и не является ни первым, ни вторым, где первый символ является ^, ни последним символом, поведение определяется реализацией.

Возможно, если MSVC не работает должным образом, это лишь один из многих примеров, когда Microsoft либо не соответствует последнему стандарту, либо думает, что знает лучше: -)

6 голосов
/ 14 мая 2011

Спецификация формата "%[" для scanf() является стандартной и применяется с C90.

MSVC поддерживает это.

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

int main()
{
    char buf[9];

    scanf("%8[^\n]",buf);

    printf("%s\n", buf);
    printf("strlen(buf) == %u\n", strlen(buf));

    return 0;
}

Также обратите внимание, что "%[" спецификация формата не означает, что scanf() поддерживает регулярные выражения.Эта конкретная спецификация формата похожа на возможность регулярных выражений (и, несомненно, на нее повлияло регулярное выражение), но она гораздо более ограничена, чем регулярные выражения.

...