char s[11];
if (scanf_s("%[a-z]s", s, 10)) printf("String1: %s\n", s);
if (scanf_s("%[a-z]s", s, 10)) printf("String2: %s\n", s);
Output:
abcABC
String1: abc
В чём причина такого поведения scanf_s и как это исправить? Если не использовать модификатор набора символов, всё работает как надо:
char s[11];
if (scanf_s("%s", s, 10)) printf("String1: %s\n", s);
if (scanf_s("%s", s, 10)) printf("String2: %s\n", s);
Output:
abc
String1: abc
XYZ
String2: XYZ
Во-первых, форматная строка "%[a-z]s" рассматривается scanf как спецификатор формата %[a-z] за которым следует посторонний самостоятельный символ s. Все самостоятельные символы в форматной строке (кроме пробельных) рассматриваются scanf как требование того, чтобы такой символ присутствовал во входной строке. В ваших входных строках никакого s нет. В результате первый scanf завершается досрочно по ошибке несоответствия формата, хоть и после успешного прочтения abc. Он возвращает 1, т.е. первый printf срабатывает.
Что такое "%[a-z]s"? Зачем вы поместили туда это s? Формат %[] является самодостаточным форматом scanf. В нем нет и никогда не было никакого s после ].
Во-вторых, при входе abcABC ваш первый scanf читает успешно abc, что вы и наблюдаете, а остаток строки - ABC - остается во входном буфере. Ваш второй scanf ничего не читает, так как вход ABC не соответствует формату %[a-z]. Если спецификатору формата не удалось ничего прочитать, scanf не читает пустую строку, а завершается досрочно по ошибке несоответствия формата. Второй scanf возвращает 0, поэтому ваш второй if не срабатывает. Как и должно быть.
В-третьих, все форматы scanf, кроме форматов %[] и %c, осуществляют изначальное пропускание пробельных символов во входном потоке, перед тем как начать собственно чтение. Если вы введете на вход вашего кода строку abc с последующим нажатием Enter, то во входном буфере образуется последовательность abc\n. Первый scanf успешно прочитает abc, но символ \n не совпадает с символом s, требуемым первым scanf. Поэтому первый scanf завершится и оставит символ \n во входном потоке. Второй scanf начнет чтение именно с этого символа \n. Так как символ \n не соответствует формату %[a-z] второй scanf ничего прочитать не сможет и вернет 0.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей