Top.Mail.Ru
Ответы

Народ, помогите, по вопросу языка СИ, команды fgets!

народ в общем я в программе объявляю строку скажем - char str[10]; - я правильно понимаю, что это означает 10 символов в массиве - от [0] до [9], а последний, [10], является \0 - заканчивающим нулём?

если так, то есть такая команда - fgets. она нужна, чтобы заполнить строку (массив символов) тем, что введёт пользователь. принимает три аргумента:
• Массив символов, в который необходимо записать вводимую строку
• Количество символов, которые может считать функция с учётом символа конца строки
• Откуда читать данные. В нашем случае указан стандартный поток ввода (stdin)

и вот хочу заполнить эту строку str полностью, то есть хочу, чтобы было введено 10 символов. Я правильно понимаю, что тогда я должен написать fgets(str,11,stdin), а не fgets(str,10,stdin)? Ведь в описании этой команды написано, что второй аргумент - это количество вводимых символов С УЧЁТОМ символа конца строки. То есть я правильно понимаю, что получается, в массиве 11 символов: с [0] по [9] - сами символы, а [10] - символ конца строки? То есть когда я хочу заполнить полностью какую-то строку, второй аргумент всегда должен быть на 1 больше? Почему-то я везде смотрю описание этой функции, и везде это значение равно тому же значению, что и при объявлении массива? Может, я чего-то не понимаю? Я уже достаточно проэкспериментировал, и остаётся только спросить тут, скажите что-нибудь
Потому что если я пишу fgets(str,10,stdin), то записывается в массиве в итоге только 9 символов, а 10-й введённый символ игнорируется!

Дополнен
Только авторизированные пользователи могут оставлять свои ответы
Дата
Популярность
Аватар пользователя
Новичок
5лет

Всё просто. 10 символов с учетом \0. Итого 9 символов + терминатор.
вариант str[10], fgets(,10,) верный.

Еще момент:
fgets читает строку вместе с переносом строки, а не только с концом строки.
т. е. при вводе hello из stdin в str будет ['h','e','l','l','o','\n','\0']

Пруф (вывод введенной строки по символам с кодом):
https://www.ideone.com/HiCVjL

Вместо символов меньше пробела выводятся? для наглядности.
Сразу обратите внимание, что hello - 5 символов, а длина возвращается 6. Именно из-за \n
Если подумаете, что strlen возвращает длину вместе с нуль-терминатором - это не так. Добавил str2 для примера.

Аватар пользователя
Оракул
5лет

это значит, что у тебя есть область памяти, в которую можно записать не более 10 байт
т. е. ты можешь записать туда не только строку в 9 символов и нуль-терминатор, но и строку поменьше, а после нуль-терминатора запихать что-то другое или просто оставить мусор
или просто интерпретировать этот массив не как строку, а как массив чисел размером в 1 байт каждое (0..255, например, если unsigned char), тогда при передаче str в функцию, ожидающую строку, можно получить мусор или вообще словить сегфолт из-за того, что она выйдет за границы 10 байт, пытаясь найти \0

что касается fgets, то у него второй аргумент - это размер самого доступного буфера в байтах, т. е. в данном случае 10
если он увидит, что вводимая строка больше буфера, он просто обрежет её до размера буфера МИНУС ОДИН и допишет \0 в последний байт
если ты запихнёшь во второй аргумент 11, то он может со слишком длинной строкой попытаться запихнуть \0 в 11-ый байт str, который вообще-то находится за пределами выделенной памяти, это является undefined behaviour и может сломать прогу