Ввод и вывод символьных строк в Си

Пожалуйста, приостановите работу AdBlock на этом веб-сайте.

Итак, строки в языке Си. Для их не предвидено отдельного типа данных, как это изготовлено в почти всех остальных языках программирования. В языке Си строчка – это массив знаков. Чтоб обозначить конец строки, употребляется символ '' , о котором мы гласили в прошлой части этого урока. На дисплее он никак не отображается, потому поглядеть на него не получится.

Создание и инициализация строки

Потому что строчка – это массив знаков, то объявление и инициализация строки подобны схожим операциям с одномерными массивами.

Последующий код иллюстрирует разные методы инициализации строк.

Объявление и инициализация строк

Рис.1 Объявление и инициализация строк

В первой строке мы просто объявляем массив из 10 знаков. Это даже не совершенно строчка, т.к. в ней отсутствует нуль-символ , пока это просто набор знаков.

2-ая строчка. Простой метод инициализации в лоб. Объявляем любой символ по отдельности. Здесь основное не запамятовать добавить нуль-символ .

3-я строчка – аналог 2-ой строки. Направьте внимание на картину. Т.к. знаков в строке справа меньше, чем частей в массиве, другие элементы заполнятся .

Четвёртая строчка. Видите ли, здесь не задан размер. Программка его вычислит автоматом и создаст массив знаков подходящий длины. При всем этом крайним будет вставлен нуль-символ .

Как вывести строчку

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

Различные способы вывода строки на экран

Рис.2 Разные методы вывода строки на экран

Видите ли, есть несколько главных методов вывести строчку на экран.

  • употреблять функцию printf со спецификатором %s
  • употреблять функцию puts
  • употреблять функцию fputs , указав в качестве второго параметра обычный поток для вывода stdout .
Интересно почитать:  Как в эксель настроить фильтр

Единственный аспект у функций puts и fputs . Направьте внимание, что функция puts переносит вывод на последующую строчку, а функция fputs не переносит.

Видите ли, с выводом всё довольно просто.

Ввод строк

С вводом строк всё незначительно труднее, чем с выводом. Простым методом будет являться последующее:

Функция gets приостанавливает работу программки, читает строчку знаков, введенных с клавиатуры, и помещает в символьный массив, имя которого передаётся функции в качестве параметра.
Окончанием работы функции gets будет являться символ, соответственный клавише ввод и записываемый в строчку как нулевой символ.
Увидели опасность? Если нет, то о ней вас разлюбезно предупредит компилятор. Дело в том, что функция gets завершает работу лишь тогда, когда юзер надавливает кнопку ввод. Это чревато тем, что мы можем выйти за рамки массива, в нашем случае — если введено наиболее 20 знаков.
К слову, ранее ошибки переполнения буфера числились самым всераспространенным типом уязвимости. Они встречаются и на данный момент, но употреблять их для взлома программ сделалось еще труднее.

Итак, что мы имеем. У нас есть задачка: записать строчку в массив ограниченного размера. Другими словами, мы должны как-то надзирать количество знаков, вводимых юзером. И здесь нам на помощь приходит функция fgets :

Функция fgets воспринимает на вход три аргумента: переменную для записи строки, размер записываемой строки и имя потока, откуда взять данные для записи в строчку, в этом случае — stdin . Как вы уже понимаете из 3 урока, stdin – это обычный поток ввода данных, обычно связанный с клавиатурой. Совершенно необязательно данные должны поступать конкретно из потока stdin , в предстоящем эту функцию мы также будем употреблять для чтения данных из файлов.

Интересно почитать:  Excel горячая клавиша удалить строку

Если в процессе выполнения данной нам программки мы введем строчку длиннее, чем 10 знаков, в массив все равно будут записаны лишь 9 знаков с начала и символ переноса строки, fgets «обрежет» строчку под нужную длину.

Направьте внимание, функция fgets считывает не 10 знаков, а 9 ! Как мы помним, в строчках крайний символ зарезервирован для нуль-символа.

Давайте это проверим. Запустим программку из крайнего листинга. И введём строчку 1234567890 . На экран выведется строчка 123456789 .

Пример работы функции fgets

Рис.3 Пример работы функции fgets

Возникает вопросец. А куда делся десятый символ? А я отвечу. Он никуда не делся, он остался в потоке ввода. Сделайте последующую программку.

Вот итог её работы.

Непустой буфер stdin

Рис.4 Непустой буфер stdin

Объясню произошедшее. Мы вызвали функцию fgets . Она открыла поток ввода и дождалась пока мы введём данные. Мы ввели с клавиатуры 1234567890n ( n я обозначаю нажатие кнопка Enter ). Это отправилось в поток ввода stdin . Функция fgets , как и полагается, взяла из потока ввода 1-ые 9 знаков 123456789 , добавила к ним нуль-символ и записала это в строчку str . В потоке ввода осталось ещё 0n .

Дальше мы объявляем переменную h . Выводим её значение на экран. Опосля чего же вызываем функцию scanf . Здесь-то ожидается, что мы можем что-то ввести, но т.к. в потоке ввода висит 0n , то функция scanf принимает это как наш ввод, и записывается 0 в переменную h . Дальше мы выводим её на экран.

Это, естественно, не совершенно такое поведение, которое мы ожидаем. Чтоб совладать с данной нам неувязкой, нужно очистить буфер ввода опосля того, как мы считали из него строчку, введённую юзером. Для этого употребляется особая функция fflush . У неё всего один параметр – поток, который необходимо очистить.

Интересно почитать:  Многоуровневая группировка строк в excel

Исправим крайний пример так, чтоб его работа была прогнозируемой.

Сейчас программка будет работать так, как следует.

Сброс буфера stdin функцией fflush

Рис.4 Сброс буфера stdin функцией fflush

Подводя результат, можно отметить два факта. 1-ый. Сейчас внедрение функции gets является опасным, потому рекомендуется всюду употреблять функцию fgets .

2-ой. Не запамятовывайте очищать буфер ввода, если используете функцию fgets .

Ссылка на основную публикацию
Adblock
detector