Почему мы должны помещать пробел в scanf ("% [^ \ n]")? - PullRequest
2 голосов
/ 28 мая 2020
size_t n;
scanf("%d", &n);

char** arr;
arr = (char**)malloc(n * sizeof(char*));

for (size_t i = 0; i < n; ++i)
{
    *(arr + i) = (char*)malloc(10000 * sizeof(char));
    scanf(" %[^\n]",*(arr+i));
    *(arr + i) = (char*)realloc(*(arr + i), strlen(*(arr + i)) + 1);
    puts(arr[i]);
}

Если в scanf("% [^\n]") нет пробела между " и % символами, код не работает. Почему надо ставить космос? Что означает этот космический символ?

1 Ответ

2 голосов
/ 28 мая 2020
  scanf(" %[^\n]", *(arr+i));

Часть " " строки формата пропускает все начальные пробелы, включая символы новой строки.

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

Без пробела следующий scanf("%[^\n]", ...) будет читать новую строку, оставленную предыдущим вызовом scanf, как первый символ, и отклонит его из-за исключения ^\n, поэтому ему не удастся найти совпадение для строки формата "%[^\n]".

С пробелом следующий scanf(" %[^\n]", ...) будет сначала прочтите и отбросьте новую строку (и любые начальные пробелы в следующей строке), затем прочтите следующую строку, как ожидалось.


[ EDIT ] В соответствующем примечании это всегда рекомендуется проверять возвращаемое значение scanf.
    if(scanf(" %[^\n]",*(arr+i)) != 1)  // nothing was matched
    {
        arr[i][0] = '\0';  // do not leave arr[i] uninitialized
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...