Основная причина для классов символов заключается в том, что нотация% s останавливается на первом символе пробела, даже если вы указываете длину поля, и вы часто этого не хотите. В этом случае нотация класса символов может быть чрезвычайно полезна.
Считайте, что этот код читает строку длиной до 10 символов, отбрасывая лишние, но оставляя пробелы:
#include <ctype.h>
#include <stdio.h>
int main(void)
{
char buffer[10+1] = "";
int rc;
while ((rc = scanf("%10[^\n]%*[^\n]", buffer)) >= 0)
{
int c = getchar();
printf("rc = %d\n", rc);
if (rc >= 0)
printf("buffer = <<%s>>\n", buffer);
buffer[0] = '\0';
}
printf("rc = %d\n", rc);
return(0);
}
На самом деле это был пример кода для обсуждения comp.lang.c.moderated (около июня 2004 г.), связанного с getline()
вариантами.
По крайней мере, некоторая путаница царит. Первый спецификатор формата, %10[^\n]
, считывает до 10 не-новых символов, и они назначаются в буфер вместе с завершающим нулем. Второй спецификатор формата, %*[^\n]
, содержит символ подавления присваивания (*
) и считывает ноль или более оставшихся символов без перевода строки из входных данных. Когда функция scanf()
завершается, ввод указывает на следующий символ новой строки. Тело цикла считывает и печатает этот символ, так что, когда цикл перезапускается, ввод смотрит на начало следующей строки. Затем процесс повторяется. Если строка короче 10 символов, то эти символы копируются в буфер, а формат «ноль или более не-новых строк» обрабатывает ноль не-новых строк.