Когда scanf добавит '\ 0' к пользовательскому вводу? - PullRequest
0 голосов
/ 28 марта 2019

Я понимаю, что scanf("%s",arr); автоматически добавит '\0' к пользовательскому вводу. Но я думал, что это было ограничено только этим. Однако даже scanf("%[^\n]",arr); также добавляет '\ 0' (я знаю, что это сканирует все символы, пока не будет достигнут символ новой строки). В этом случае '\0' будет добавлено после '\n' или до '\n'. Кроме того, как мы узнаем, когда и когда не будет добавлено '\0'? Как мы сканируем много символов, чтобы сформировать массив символов, а не строку?

1 Ответ

3 голосов
/ 28 марта 2019

Кроме того, как мы выясним, когда и когда не будет добавлено '\ 0'?

Поскольку scanf является стандартной функцией, мы выясним это из стандарта C,Начиная с C11 черновика 7.21.6.2p12 :

s
... соответствующий аргумент должен быть указателем на начальный элемент массива символов, достаточно большой, чтобы принятьпоследовательность и завершающий нулевой символ, который будет добавлен автоматически....

[
... соответствующий аргумент должен быть указателем на начальный элемент массива символов, достаточно большой, чтобы принять последовательность, и завершающий нулевой символ, который будет добавлен автоматически....

Более привлекательный и часто используемый для быстрой ссылки сайт cppreference .

Я настоятельно рекомендую вам никогда не использовать %sи %[ без числа, указывающего «максимальную ширину поля» (если вы не знаете, что можете его использовать).Всегда используйте %<number>s и %<number>[, чтобы ограничить количество прочитанных символов и предотвратить переполнение.Так что всегда:

char arr[20];
scanf("%19s", arr);

scanf - это очень небезопасная функция, поэтому переполнение стека легко выполнять при чтении строк.

Как это сделатьмы сканируем много символов, чтобы просто сформировать массив символов, а не строку?

Я думаю, вы хотите:

size_t fread (void * ограничение ptr, size_t size, size_tnmemb, FILE * ограничить поток);

Функция fread считывает в массив, на который указывает ptr, до элементов nmemb, размер которых определяется размером, из потока, на который указывает поток.

Будет считано nmemb элементов размером size в память, указанную ptr.Так что просто:

 char character_array[20];
 size_t number_of_chcaracter_read = fread(character_array, 20, 1, stdin);

Он не будет добавлять завершающий нулевой байт к character_array.

...