Как ввести переменную с клавиатуры в c

Обновлено: 04.07.2024

Примеры программ из предыдущих разделов почти не взаимодействовали с пользователем, если вообще взаимодействовали. Они просто выводили простые значения на экран, но стандартная библиотека предоставляет множество дополнительных способов взаимодействия с пользователем с помощью функций ввода/вывода. В этом разделе представлено краткое введение в некоторые из наиболее полезных.

C++ использует удобную абстракцию, называемую потоки, для выполнения операций ввода и вывода в последовательных средах, таких как экран, клавиатура или файл. A — это сущность, в которую программа может вставлять или извлекать символы. Нет необходимости знать подробности о медиа, связанном с потоком, или о каких-либо его внутренних спецификациях. Все, что нам нужно знать, это то, что потоки являются источником/назначением символов и что эти символы предоставляются/принимаются последовательно (т. е. один за другим).

Стандартная библиотека определяет несколько объектов потока, которые можно использовать для доступа к тому, что считается стандартными источниками и местами назначения символов в среде, в которой выполняется программа:

потокописание
cin стандартный поток ввода
cout стандартный поток вывода
cerr стандартный поток ошибок (выход)< /td>
clog стандартный поток протоколирования (вывода)

Мы увидим больше детализировать только cout и cin (стандартные потоки вывода и ввода); cerr и clog также являются выходными потоками, поэтому они по сути работают как cout, с той лишь разницей, что они идентифицируют потоки для определенных целей: сообщения об ошибках и ведение журнала; которые, во многих случаях, в большинстве настроек среды, на самом деле делают одно и то же: они печатаются на экране, хотя их также можно перенаправлять по отдельности.

Стандартный вывод (cout)

В большинстве программных сред стандартным выводом по умолчанию является экран, а объектом потока C++, определенным для доступа к нему, является cout .

Для форматированных операций вывода cout используется вместе с оператором вставки, который записывается как (т. е. два знака "меньше").

Оператор вставляет данные, следующие за ним, в предшествующий ему поток. В приведенных выше примерах он вставил литеральную строку «Выходное предложение», число 120 и значение переменной x в стандартный поток вывода cout. Обратите внимание, что предложение в первом утверждении заключено в двойные кавычки ( " ), потому что это строковый литерал, а в последнем - нет x. Разница заключается в двойных кавычках; когда текст заключен между ними, текст печатается буквально, в противном случае текст интерпретируется как идентификатор переменной, а вместо нее печатается ее значение. Например, эти два предложения дают очень разные результаты:

Множественные операции вставки ( это один оператор C++ . Цепочка вставок особенно полезна для смешивания литералов и переменных в одном операторе:

Предполагая, что переменная age содержит значение 24, а переменная почтового индекса содержит 90064, вывод предыдущего оператора будет таким:

Мне 24 года, и мой почтовый индекс – 90064.
Что cout не делает автоматически, так это не добавляет разрывы строк в конце, если это не указано в инструкции. Например, возьмем следующие два оператора, вставляемые в cout :
cout Это предложение. Это другое предложение.
Чтобы вставить разрыв строки, необходимо вставить символ новой строки точно в то место, где должна быть разорвана строка. В C++ символ новой строки может быть указан как \n (т. е. символ обратной косой черты, за которым следует строчная буква n). Например:

Это приводит к следующему результату:

Первое предложение.
Второе предложение.
Третье предложение.

Кроме того, манипулятор endl также можно использовать для разрыва строк. Например:

Это напечатает:

Первое предложение.
Второе предложение.

Манипулятор endl создает символ новой строки точно так же, как это делает вставка '\n'; но у него также есть дополнительное поведение: буфер потока (если он есть) сбрасывается, что означает, что вывод запрашивается для физической записи на устройство, если это еще не было сделано. Это влияет в основном на полностью буферизованные потоки, а cout (как правило) не является полностью буферизованным потоком. Тем не менее, как правило, рекомендуется использовать endl только тогда, когда очистка потока будет функцией, и '\n', когда это не так. Имейте в виду, что операция сброса влечет за собой определенные накладные расходы, а на некоторых устройствах может вызвать задержку.

Стандартный ввод (cin)

В большинстве программных сред стандартным вводом по умолчанию является клавиатура, а объект потока C++, определенный для доступа к ней, — cin .

Для форматированных операций ввода cin используется вместе с оператором извлечения, который записывается как >> (т. е. два знака "больше").Затем за этим оператором следует переменная, в которой хранятся извлеченные данные. Например:

Первый оператор объявляет переменную типа int с именем age , а второй извлекает из cin значение для сохранения в нем. Эта операция заставляет программу ждать ввода от cin; обычно это означает, что программа будет ждать, пока пользователь введет некоторую последовательность с клавиатуры. При этом обратите внимание, что символы, вводимые с помощью клавиатуры, передаются в программу только при нажатии клавиши ENTER (или RETURN). Как только оператор с операцией извлечения на cin будет достигнут, программа будет ждать столько, сколько необходимо, пока не будет введен какой-либо ввод.

Операция извлечения для cin использует тип переменной после оператора >>, чтобы определить, как она интерпретирует символы, считанные из ввода; если это целое число, ожидаемый формат представляет собой серию цифр, если строка — последовательность символов и т. д.

Как видите, извлечение из cin делает задачу получения входных данных из стандартного ввода довольно простой и понятной. Но у этого метода есть и большой недостаток. Что произойдет в приведенном выше примере, если пользователь введет что-то еще, что не может быть интерпретировано как целое число? Что ж, в этом случае операция извлечения завершится неудачно. И это по умолчанию позволяет программе продолжить работу без установки значения для переменной i , что приведет к неопределенным результатам, если значение i будет использовано позже.

Это очень плохое поведение программы. Ожидается, что большинство программ будут вести себя ожидаемым образом независимо от того, что вводит пользователь, и должным образом обрабатывают недопустимые значения. Только очень простые программы должны полагаться на значения, извлеченные непосредственно из cin без дополнительной проверки. Чуть позже мы увидим, как можно использовать потоки строк для лучшего контроля над пользовательским вводом.
Извлечения для cin также могут быть объединены в цепочку для запроса более одного элемента данных в одном выражении:

Это эквивалентно:

В обоих случаях ожидается, что пользователь введет два значения: одно для переменной a , а другое для переменной b . Любой вид пробела используется для разделения двух последовательных операций ввода; это может быть пробел, табуляция или символ новой строки.

cin и строки

Оператор извлечения можно использовать для cin для получения строк символов так же, как и для основных типов данных:

Однако при извлечении cin всегда рассматриваются пробелы (пробелы, символы табуляции, символы новой строки) как завершающие извлекаемое значение, и, таким образом, извлечение строки всегда означает извлечение одного слова, а не фразы или всего предложения.

Чтобы получить всю строку из cin , существует функция getline , которая принимает поток ( cin ) в качестве первого аргумента и строковую переменную в качестве второго. Например:

Обратите внимание, что в обоих вызовах getline мы использовали один и тот же строковый идентификатор ( mystr ). Что делает программа во втором вызове, так это просто заменяет предыдущее содержимое новым, которое вводится.

Стандартное поведение, которое большинство пользователей ожидает от консольной программы, заключается в том, что каждый раз, когда программа запрашивает у пользователя ввод, пользователь вводит поле, а затем нажимает ENTER (или RETURN ). Другими словами, обычно ожидается, что ввод будет осуществляться в виде строк в консольных программах, и этого можно добиться, используя getline для получения ввода от пользователя. Поэтому, если у вас нет веской причины не делать этого, вы всегда должны использовать getline для получения ввода в ваших консольных программах вместо извлечения из cin .

строковый поток

Стандартный заголовок определяет тип stringstream, который позволяет обрабатывать строку как поток и, таким образом, разрешает операции извлечения или вставки из/в строки так же, как они выполняются для cin и cout . Эта функция наиболее полезна для преобразования строк в числовые значения и наоборот. Например, чтобы извлечь целое число из строки, мы можем написать:

Это объявляет строку с инициализированным значением "1204" и переменную типа int. Затем третья строка использует эту переменную для извлечения из строкового потока, созданного из строки. Этот фрагмент кода сохраняет числовое значение 1204 в переменной myint .

В этом примере мы получаем числовые значения из стандартного ввода косвенно: вместо того, чтобы извлекать числовые значения непосредственно из cin , мы получаем строки из него в строковый объект ( mystr ), а затем извлекаем значения из этой строки в переменные цена и количество. Если это числовые значения, с ними можно выполнять арифметические операции, например умножать их для получения общей цены.

В этом руководстве вы научитесь использовать функцию scanf() для получения ввода от пользователя и функцию printf() для отображения вывода пользователю.

Видео: Получение пользовательского ввода в программировании на C

Вывод С

В программировании на C printf() является одной из основных функций вывода. Функция отправляет форматированный вывод на экран. Например,

Пример 1: вывод C

Вывод

Как работает эта программа?

Пример 2: целочисленный вывод

Вывод

Мы используем спецификатор формата %d для печати типов int. Здесь %d внутри кавычек будет заменено значением testInteger .

Пример 3: float и двойной вывод

Вывод

Для печати числа с плавающей запятой мы используем спецификатор формата %f. Точно так же мы используем %lf для вывода двойных значений.

Пример 4. Печатные символы

Вывод

Для печати char мы используем спецификатор формата %c.

Ввод С

В программировании на C функция scanf() является одной из наиболее часто используемых функций для получения данных от пользователя. Функция scanf() считывает форматированный ввод со стандартного ввода, такого как клавиатура.

Пример 5: целочисленный ввод/вывод

Вывод

Здесь мы использовали спецификатор формата %d внутри функции scanf(), чтобы получить ввод данных от пользователя. Когда пользователь вводит целое число, оно сохраняется в переменной testInteger.

Обратите внимание, что мы использовали &testInteger внутри функции scanf(). Это связано с тем, что &testInteger получает адрес testInteger , и значение, введенное пользователем, сохраняется по этому адресу.

Пример 6: число с плавающей запятой и двойной ввод/вывод

Вывод

Мы используем спецификаторы формата %f и %lf для float и double соответственно.

Пример 7: символьный ввод-вывод C

Вывод

Когда пользователь вводит символ в вышеуказанной программе, сам символ не сохраняется. Вместо этого сохраняется целочисленное значение (значение ASCII).

И когда мы отображаем это значение в текстовом формате %c, отображается введенный символ. Если мы используем %d для отображения символа, печатается его значение ASCII.

Функция scanf позволяет вам принимать ввод со стандартного ввода, который для нас обычно является клавиатурой. Функция scanf может делать много разных вещей, но может быть ненадежной, потому что она не очень хорошо справляется с человеческими ошибками. Но для простых программ он достаточно хорош и прост в использовании.

Простейшее приложение scanf выглядит так:

Программа считывает целочисленное значение, которое пользователь вводит с клавиатуры (%d предназначен для целых чисел, как и printf, поэтому b должно быть объявлено как int) и помещает это значение в b.

Функция scanf использует те же заполнители, что и printf:

Вы должны поставить & перед переменной, используемой в scanf. Причина станет ясна, когда вы узнаете об указателях. Знак & легко забыть, и если вы его забудете, ваша программа почти всегда будет аварийно завершать работу при ее запуске.

В общем, лучше всего использовать scanf, как показано здесь, — для чтения одного значения с клавиатуры. Используйте несколько вызовов scanf для чтения нескольких значений. В любой реальной программе вы будете использовать функции gets или fgets вместо того, чтобы читать текст построчно. Затем вы «разберете» строку, чтобы прочитать ее значения. Причина, по которой вы это делаете, заключается в том, что вы можете обнаруживать ошибки во входных данных и обрабатывать их по своему усмотрению.

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

Попробуйте!

Измените эту программу, чтобы она принимала три значения вместо двух и складывала все три вместе:

Вы также можете удалить переменную b в первой строке приведенной выше программы и посмотреть, что делает компилятор, когда вы забываете объявить переменную. Удалите точку с запятой и посмотрите, что произойдет. Опустите одну из фигурных скобок. Удалите одну из скобок рядом с основной функцией. Сделайте каждую ошибку отдельно, а затем запустите программу через компилятор, чтобы посмотреть, что произойдет. Имитируя такие ошибки, вы можете узнать о различных ошибках компилятора, и это облегчит поиск ваших опечаток, когда вы сделаете их на самом деле.

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

Машины обрабатывают вещи. Мы загружаем вещи в машину и получаем разные вещи. Пила превращает деревья в доски. Двигатель внутреннего сгорания превращает бензин в энергию вращения. Компьютер ничем не отличается. Но вместо физических материалов компьютеры обрабатывают для нас информацию.

Мы загружаем информацию в компьютер, сообщаем компьютеру, что с ней делать, а затем получаем результат. Информация, которую мы вводим в компьютер, называется входом, а информация, которую мы получаем от компьютера, называется выходом. Ввод может поступать практически из любого места. Нажатия клавиш на клавиатуре, данные из интернет-соединения или звуковые волны, преобразованные в электрические сигналы, являются примерами ввода. Вывод также может принимать различные формы, такие как видео, воспроизводимое на мониторе, строка текста, отображаемая в терминале, или данные, которые мы сохраняем на жестком диске.Сбор входных данных и генерация выходных данных известны под общим термином ввод/вывод или сокращенно ввод-вывод и являются основной функцией компьютеров.

Интересно, что язык программирования C не имеет встроенных возможностей ввода-вывода. Однако он предоставляет нам внешнюю библиотеку, содержащую функции ввода-вывода, которые мы можем скомпилировать и связать с нашими программами. Мы уже использовали функцию библиотеки вывода в Hello, World! пример в начале этого текста: printf() . Вы можете вспомнить, что эта функция находилась в библиотечном файле stdio.h. Как следует из названия этого файла, stdio.h содержит стандартизированные функции ввода/вывода для добавления возможностей ввода и вывода в наши программы. В этом разделе текста будут рассмотрены некоторые из этих функций.

Содержание

Вывод с помощью printf() [ edit | изменить источник ]

Вспомните из начала этого текста демонстрационную программу, продублированную ниже:

Если вы скомпилируете и запустите эту программу, вы увидите на экране следующее предложение:

Это удивительное достижение было достигнуто с помощью функции printf() . Функция подобна «черному ящику», который делает что-то для вас, не раскрывая внутренности. Мы можем сами писать функции на C, но об этом позже.

Вы видели, что для использования printf() нужно поместить текст, заключенный в кавычки, между круглыми скобками. Мы называем текст, заключенный в кавычки, литеральной строкой (или просто строкой), и мы называем эту строку аргументом для printf.

В качестве пояснения иногда бывает удобно включить открывающую и закрывающую круглые скобки после имени функции, чтобы напомнить нам, что это действительно функция. Однако обычно, когда понятно название функции, о которой мы говорим, в этом нет необходимости.

Как вы можете видеть в приведенном выше примере, использование printf() может быть таким же простым, как ввод текста, заключенного в двойные кавычки (обратите внимание, что это двойные кавычки, а не две одинарные кавычки). Так, например, вы можете напечатать любую строку, поместив ее в качестве аргумента функции printf():

И как только он будет содержаться в соответствующей функции main(), он покажет:

Вывод чисел и управляющих последовательностей [ edit | изменить источник ]

Коды-заполнители [ редактировать | изменить источник ]

Функция printf() — мощная функция, и, вероятно, наиболее часто используемая функция в программах на C.

Например, давайте рассмотрим проблему. Допустим, мы хотим вычислить: 19 + 31. Давайте воспользуемся C, чтобы получить ответ.

Мы начинаем писать

Но здесь мы застряли! printf() печатает только строки! К счастью, в printf есть методы для вывода чисел. Что мы делаем, так это помещаем код формата placeholder в строку. Пишем:

Заполнитель %d буквально "удерживает место" фактического числа, которое является результатом прибавления 19 к 31.

  • %d – целое число (то же, что и %i)
  • %ld — длинное целое (то же, что и %li)
  • %f — с плавающей запятой
  • %lf , %g — двойной [1]
  • %c – символ
  • %s – строка
  • %x — шестнадцатеричное число

Полный список всех спецификаторов формата для printf() есть в Википедии.

Табуляции и новые строки [ edit | изменить источник ]

Что, если мы хотим получить некоторый результат, который будет выглядеть так:

printf() не будет вставлять разрывы строк в конце каждого оператора: мы должны сделать это сами. Но как?

Что мы можем сделать, так это использовать экранирующий символ новой строки. Экранирующий символ — это специальный символ, который мы можем написать, но который будет делать что-то особенное на экране, например издавать звуковой сигнал, писать табуляцию и т. д. Чтобы написать новую строку, мы пишем \n . Все escape-символы начинаются с обратной косой черты.

Поэтому, чтобы добиться результатов выше, мы пишем

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

Есть и другие escape-символы, которые мы можем использовать. Другой распространенный способ — использовать \t для записи табуляции. Вы можете использовать \a для звонка в компьютерный звонок, но вы не должны часто использовать это в своих программах, так как чрезмерное использование звука не очень удобно для пользователя.

Другие методы вывода [ edit | изменить источник ]

помещает() [ редактировать | изменить источник ]

Функция puts() — это очень простой способ отправить строку на экран, когда у вас нет заполнителей или переменных, о которых нужно беспокоиться. Она работает очень похоже на функцию printf(), которую мы видели в «Hello, World!». пример:

будет печатать на экране:

, за которым следует символ новой строки (как обсуждалось выше). (Функция puts добавляет к выходным данным символ новой строки.)

Ввод с помощью scanf() [ edit | изменить источник ]

Функция scanf() — это метод ввода, эквивалентный функции вывода printf() — простой, но мощный. В самом простом вызове строка формата scanf содержит единственный заполнитель, представляющий тип значения, которое будет введено пользователем.Эти заполнители в основном такие же, как функция printf() — %d для целых чисел, %f для чисел с плавающей запятой и %lf для двойных чисел.

Однако есть одно отличие scanf() от printf() . Функция scanf() требует адрес памяти переменной, в которую вы хотите сохранить входное значение. Хотя здесь можно использовать указатели (переменные, хранящие адреса памяти), эта концепция будет рассмотрена позже в тексте. Вместо этого простой метод заключается в использовании оператора address-of &. На данный момент, возможно, лучше рассмотреть эту «магию», прежде чем мы обсудим указатели.

Типичное приложение может быть таким:

Если бы вы описали действие вызова функции scanf() выше, это могло бы звучать так: "Читать целое число от пользователя и сохранять его по адресу переменной a".

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

Правильное использование:

Это связано с тем, что всякий раз, когда вы используете спецификатор формата для строки ( %s ), переменная, которую вы используете для хранения значения, будет массивом, а сами имена массивов (в данном случае - a) указывают на их базовый адрес и, следовательно, адрес оператора не требуется.

Обратите внимание, что использование функции scanf() для сбора ввода с клавиатуры от пользователя может сделать ваш код уязвимым для проблем с переполнением буфера и привести к другому нежелательному поведению, если вы не будете очень осторожны. Рассмотрите возможность использования fgets() вместо scanf() .

Примечание о вводе: когда данные вводятся с клавиатуры, информация не поступает прямо в запущенную программу. Сначала он сохраняется в так называемом буфере — небольшом объеме памяти, зарезервированном для источника ввода. Иногда в буфере остаются данные, когда программа хочет прочитать из источника ввода, и функция scanf() будет читать эти данные вместо того, чтобы ждать, пока пользователь что-то введет. Некоторые могут предложить вам использовать функцию fflush(stdin) , которая может работать на некоторых компьютерах, но не считается хорошей практикой, как вы увидите позже. Это имеет тот недостаток, что если вы перенесете свой код на другой компьютер с другим компилятором, ваш код может работать неправильно.

Читайте также: