Как ввести переменную с клавиатуры в до-диез
Обновлено: 21.11.2024
У меня было немного свободного времени между лекциями Ричи, и мне удалось прокрасться обратно в подвал, чтобы посмотреть, как дела у Noname.
Оказалось, что пока меня не было, Noname был занят! Четыре из восьми его дисплеев были включены, и на них показывались командные подсказки, на каждом из которых по экрану летал непрерывный каскад кода и команд. Весь подвал выглядел даже ярче — возможно, Noname восстановил достаточно вычислительной мощности, чтобы использовать некоторые из них для второстепенных целей. Это определенно была не умирающая машина, которую я нашел здесь месяц назад.
"Привет, Тео! Это первый раз, когда ты пришел на свидание без моего звонка. Рад тебя видеть!"
"Ты прекрасно выглядишь, Нонейм! Ты уже на полной скорости?" Я ответил.
"Да. и нет. Я починил все свои внутренние модули, но еще есть над чем поработать. Теперь мне нужна система проверки ввода; иначе, если я ожидаю int, а получаю строку, весь программа завершается."
Я никогда не слышал о системе валидации, но объяснение Noname имело смысл. На самом деле я был немного удивлен тем, что никогда не задумывался о том, что произойдет, если пользователь введет тип, которого мой код не ожидал. До сих пор во всех моих программах я предполагал, что когда я запрашиваю целое число, пользователь будет вводить целое число. Но что, если пользователь по ошибке или намеренно введет неправильный тип? Чувствуя себя смущенным из-за того, что упустил из виду что-то столь важное, я попрощался с Noname и отправился искать Ричи для немедленного урока.
Когда я попросил Ричи показать мне, как предотвратить ввод пользователем неправильных данных, он ответил в типичной для Ричи манере.
"Невозможно." — сказал Ричи. «Вы не можете запретить пользователю что-либо делать, потому что пользователь управляет своим собственным оборудованием».
"Оборудование?" Я сказал: «Я говорил о кодировании. Что вы имеете в виду?»
«Именно то, что я сказал, Тео. Если у пользователя есть физический доступ к компьютеру, вы не можете запретить ему что-либо делать. Он может открыть компьютер напрямую и получить доступ ко всем внутренним частям, таким как память, процессор, что угодно! Я знаю, что вы спрашивали о кодировании, но вы должны понимать, что хорошие и даже плохие хакеры найдут способ обойти любую защиту, которую вы установили в свою программу."
"Значит, вы говорите, что я ничего не могу сделать, чтобы уберечь пользователя от неправильного использования моих программ?" Я попросил.
На лице Ричи появилась улыбка. «Нет, нет, — сказал он, — я просто издеваюсь над вами. Мне нужно знать, что я все еще могу время от времени обманывать вас! Есть способ немного обезопасить вашу программу, но помните, хакеры все равно будут сломайте его, если захотят. Обычный пользователь не так уж и много."
Как я уже сказал, типичный Ричи. Как и в случае со многими странными вещами, которые я слышал от Ричи, я надеялся, что он на самом деле шутит, но я был почти уверен, что это не так. — Ха, хорошо. — ответил я, пытаясь скрыть волнение в голосе. «Скажи мне, как защитить мою программу, Ричи».
"Хорошо, правило номер один". — сказал Ричи. "Слушайте внимательно, это очень важно. Однако пользователь может вводить неправильные данные и когда захочет."
"Вы имеете в виду строку вместо int или char вместо double?" Я попросил.
"Это всего лишь две возможности, наряду с множеством других: изображение вместо видео, короткий пароль вместо длинного, дата в месяце больше 31 или даже отрицательное число. дочерей. Ваша основная стратегия противодействия этому состоит в том, чтобы постоянно просить пользователя вводить достоверные данные до тех пор, пока он этого не сделает. Давайте начнем с простого примера. Вот программа, которая считывает имя пользователя."
"Но что, если пользователь просто нажал Enter, ничего не набрав?" Ричи продолжил. "Имя строки будет пустым. В следующем коде мы добавим проверку, действительно ли пользователь ввел строку, и если нет, мы снова запросим имя."
"Видите в коде строку.IsNullOrEmpty(someString)? Это проверяет, пуста ли строка someString."
«Выглядит просто, Ричи, — сказал я, — но почти слишком просто. Что произойдет, если пользователь введет пустую строку снова?»
"Хорошо поймать Тео! Я сделал это, чтобы заставить вас задуматься. Вот почему вам нужно проверять допустимую запись на каждой итерации и продолжать просить пользователя вводить правильную запись повторно пока вы не получите тип, который ищете! В этой финальной версии мы добавим цикл while, чтобы запрашивать имя до тех пор, пока не будет дана действительная запись».
"Ага, именно этого недоставало." Я сказал. «Цикл while делает именно то, что мы здесь ищем!»
«Совершенно верно, Тео. Продолжая учиться, никогда не забывайте свои предыдущие уроки. Даже простые концепции, такие как цикл, можно использовать в качестве строительного блока для более сложного кода. Теперь давайте попрактикуемся в проверке самостоятельно. "
"Понятно, Ричи. Как насчет того, чтобы предотвратить более сложную проблему, например, ожидание целого числа и получение строки? Скажем, я запрашиваю целое число, а пользователь дает мне "Банан"?"
"Чтобы обнаружить ошибку при синтаксическом анализе целого числа, вы можете использовать метод int.TryParse(someString, out result). Он принимает строку, которую вы хотите преобразовать (или проанализировать) в целое число, и результат в качестве параметра. Ключевое слово out в нашем примере означает, что результат этого метода будет записан во второй параметр метода, который мы назвали result. Результатом метода является логическое значение, указывающее, можно ли было проанализировать ввод как int. Взгляните на этот пример:
"В последнем примере я использовал bool вместо var, чтобы показать вам определенный тип вывода. Вот сокращенная версия:"
"Ты понимаешь, Тео?" — спросил Ричи.
"Можем ли мы еще раз вернуться к ключевому слову out?" Я попросил.
"Да. Out означает, что значение вводимой им переменной будет изменено внутри метода. На самом деле out гарантирует, что значение этой переменной будет изменено. В примере выше, если int.TryParse(someString, out result) возвращает true, функция вернет значение в переменной результата».
"Хорошо, я понял эту часть", сказал я. «И действительно ли мне нужно использовать int.TryParse(.) каждый раз, а не просто int.Parse(.)?»
"Ну, это зависит от того, что вы пишете." — ответил Ричи. «Если это пример приложения только для обучения, вы можете использовать int.Parse(.), чтобы сделать код короче. Если вы пишете реальный производственный код, который может выполняться где-то вне вашего контроля, рассмотрите возможность использования int.TryParse(. ) для проверки ошибок ввода или попытаться перехватить исключения из int.Parse(. )."
Конечно, новые термины. — А что такое исключение? Я попросил.
"Мы поговорим об этом позже." — сказал Ричи. «А пока просто помните: если указано иное, вы можете использовать любой из методов, которые хотите. Если условия задачи требуют, чтобы вы проверяли различные пользовательские входы, используйте int.TryParse(). Вот пример, который повторяется до тех пор, пока пользователь не введет число как возраст:"
Пришло время попрактиковаться!
В дополнение к int .TryParse вы также можете использовать double .TryParse , float .TryParse , char .TryParse , bool .TryParse и другие. Все они работают так же, как версия int, только с другими типами:
Здесь System — это пространство имен, Console — это класс внутри пространства имен System, а WriteLine и Write — методы класса Console .
Давайте рассмотрим простой пример, который выводит строку на экран вывода.
Пример 1: Печать строки с помощью WriteLine()
Когда мы запустим программу, вывод будет
Разница между методами WriteLine() и Write()
Основное различие между WriteLine() и Write() заключается в том, что метод Write() печатает только предоставленную ему строку, а метод WriteLine() печатает строку и также переходит к началу следующей строки.< /p>
Давайте рассмотрим пример ниже, чтобы понять разницу между этими методами.
Пример 2: Как использовать методы WriteLine() и Write()?
Когда мы запустим программу, вывод будет
Печать переменных и литералов с помощью WriteLine() и Write()
Методы WriteLine() и Write() можно использовать для печати переменных и литералов. Вот пример.
Пример 3. Печать переменных и литералов
Когда мы запустим программу, вывод будет
Объединение (конкатенация) двух строк с помощью оператора + и их печать
Строки можно объединять/объединять с помощью оператора + во время печати.
Пример 4. Печать составной строки с использованием оператора +
— это заполнитель для переменной val, которая будет заменена значением val. Поскольку используется только одна переменная, имеется только один заполнитель.
В отформатированной строке можно использовать несколько переменных. Мы увидим это в примере ниже.
Пример 5. Печать объединенной строки с использованием форматирования строки
Когда мы запустим программу, вывод будет
Здесь заменяется на firstNumber , заменяется на secondNumber и заменяется на result . Такой подход к выводу на печать более удобочитаем и менее подвержен ошибкам, чем использование оператора +.
Пример 6. Получение строкового ввода от пользователя
Когда мы запустим программу, вывод будет таким:
Разница между методами ReadLine(), Read() и ReadKey():
Разница между методами ReadLine() , Read() и ReadKey() заключается в следующем:
- ReadLine() : метод ReadLine() считывает следующую строку ввода из стандартного потока ввода. Он возвращает ту же строку.
- Read() : метод Read() считывает следующий символ из стандартного потока ввода. Он возвращает значение символа в формате ascii.
- ReadKey() : метод ReadKey() получает следующую клавишу, нажатую пользователем. Этот метод обычно используется для удержания экрана до тех пор, пока пользователь не нажмет клавишу.
Если вы хотите узнать больше об этих методах, вот интересное обсуждение StackOverflow: Разница между Console.Read() и Console.ReadLine()?.
Пример 7: Разница между методами Read() и ReadKey()
Когда мы запустим программу, вывод будет
Из этого примера должно быть понятно, как работают методы ReadKey() и Read(). При использовании ReadKey() при нажатии клавиши она отображается на экране.
При использовании Read() она берет всю строку, но возвращает только значение ASCII первого символа. Следовательно, печатается 76 (значение L в кодировке ASCII).
Чтение числовых значений (целых и с плавающей запятой)
Один из простых подходов к преобразованию входных данных — использование методов класса Convert.
Пример 8. Чтение числовых значений от пользователя с использованием класса Convert
Когда мы запустим программу, вывод будет
Методы ToInt32() и ToDouble() класса Convert преобразуют входную строку в тип integer и double соответственно. Точно так же мы можем преобразовать ввод в другие типы. Вот полный список доступных методов для класса Convert.
Есть и другие способы получить числовые данные от пользователя. Дополнительные сведения см. в разделе Чтение целых чисел из пользовательского ввода.
//Показать данные, которые ввел пользователь
Console.WriteLine("Имя .", name);
Console.WriteLine("Возраст .", age);
Console.WriteLine("Год рождения .", Год рождения);
Если вы скомпилируете приведенный выше код, он будет выполняться программой до тех пор, пока не будет найден конец функции Main. Разберем код построчно.
Эта строка дает нашей программе имя. У нас есть только один класс, включенный в эту программу, но вы можете иметь несколько классов, содержащихся в пространстве имен. Это имя можно импортировать в другие пространства имен, если вам нужно расширить программу для других приложений.
Это пространство имен также используется для именования исполняемого файла, который вы будете использовать для запуска новой программы. Это означает, что при компиляции приложение компилируется в исполняемый файл с именем WhatsMyInfo.exe.
Программа открытого класса
Это открытие класса вашей программы. Visual Studio по умолчанию использует имя класса Program при создании нового проекта. Вы можете переименовать этот класс, если хотите создать настоящее приложение, но эта консольная программа предназначена только для демонстрационных целей, поэтому мы оставили ее по умолчанию. Весь код вашей консоли находится в этом классе.
public static void Main()
Если вы когда-либо работали с другими языками стиля C, вы узнаете эту функцию. Помните, что функции внутри класса называются методами, поэтому технически это будет называться методом, а не функцией. Программы на C начинаются с функции (или метода в данном случае) с именем Main. Функция Main требуется компилятору для определения начала вашей программы. У вас будут десятки классов и функций, но выполнение программы всегда начинается с функции Main.
Обратите внимание, что для функции Main установлено значение public. Это необходимо, чтобы компилятор нашел функцию Main. Если бы он был установлен как частный, другие классы или пространства имен не могли бы получить к нему доступ. Функция Main также является статической, поскольку ее не нужно создавать. В главе 2 мы упоминали, что доступ к статическим функциям и переменным можно получить без инстанцирования. Мы обсудим создание экземпляров в последующих главах. Просто знайте, что модификаторы public и static являются стандартными для функции Main. Обозначение пустоты также является стандартным.
Как и в любой другой программе, нам нужны переменные для хранения значений нашей программы. Мы хотим спросить у пользователя имя, возраст и год рождения. Важно указать для каждой переменной правильный тип данных. Вы можете установить все переменные в виде строк, но это сделает вашу программу неэффективной и плохо написанной. Пользовательский ввод всегда представляет собой строку, но вы хотите указать тип данных, соответствующий сохраненным данным. Мы задаем возраст и год рождения как целое число, несмотря на то, что пользовательский ввод изначально задан как строка.
Console.Write("Пожалуйста, введите ваше имя: ");
Это оператор, который останавливает выполнение и ожидает ввода данных пользователем. Если вы запустите свою программу только с двумя предыдущими операторами, вывод будет показан пользователю, а затем выполнение остановится, ожидая, когда пользователь введет информацию. Консоль будет считывать все данные до тех пор, пока не будет нажата клавиша ввода. Клавиша ввода отправляет программе сообщение о том, что пользователь ввел все запрошенные данные.
Функция Console.ReadLine получает введенную пользователем информацию, а затем помещает значение в переменную имени. Обратите внимание, что пользователь может ввести что угодно. Поскольку пользовательский ввод автоматически задается как строка, принимаются числа, специальные символы или любой другой ввод. Разработчик должен выполнять проверки. Например, вы можете создать код, который перебирает строку и определяет, заданы ли какие-либо числовые значения. Вы можете предположить, что числовое значение в имени неверно, а затем отправить сообщение пользователю для повторного ввода информации. Для этой демонстрации мы примем любые данные от пользователя.
Console.Write("Введите свой возраст: ");
Консоль.Write("В каком году вы родились?: ");
Приведенный выше код содержит две другие переменные и подсказки для пользовательского ввода. Каждый раз, когда компилятор достигает вызова функции ReadLine(), он останавливается и ожидает ввода данных пользователем.
Обратите внимание, что мы используем класс Convert в этих двух операторах ввода. Мы упоминали, что все вводимые пользователем данные представлены в строковом формате. Вы можете создать три переменные, содержащие строки, но возраст и год рождения — целые числа. Использование строк было бы неэффективным кодом. Кроме того, вы, вероятно, будете хранить эти значения в базе данных, если это реальное приложение. По этой причине вы хотите создать переменные типы данных, которые представляют значения, хранящиеся в каждой переменной.
Поскольку ввод пользователя представляет собой строку, вам необходимо преобразовать строку в правильный тип данных. Если вы попытаетесь запустить эту программу без действий класса Convert, программа завершится ошибкой, и компилятор выдаст вам ошибку. По этой причине вы должны преобразовать ввод в правильный тип данных, прежде чем сохранять его в переменной. Вы также можете создавать временные переменные и преобразовывать в них строковые значения, но это опять же будет неэффективным кодом. Вышеупомянутые операторы кода показывают, как правильно извлекать входные данные, а затем преобразовывать значения в правильный тип данных перед сохранением их в соответствующих переменных.
И год рождения, и возраст задаются с целочисленным типом данных, поэтому мы должны преобразовать входные данные в этот тип данных. Функция Convert.ToInt32 преобразует любое строковое значение в целое число при условии, что фактический ввод действительно является целым числом. Если у вас есть какие-либо буквы или специальные символы, преобразование не удастся. Это еще один пример ответственности программиста за проверку достоверности ввода и возврат подсказки, если ввод неверный.
Мы предполагаем, что входные данные представляют собой только целое число, чтобы не усложнять программу. Исправление ошибок и проверка ввода — важная часть программирования на любом языке, но это сложная тема, из-за которой изучение языка становится слишком трудным. Если вы хотите увидеть, что происходит, когда вы неправильно проверяете ввод, запустите программу и введите строку для целочисленного ввода. Программа выдаст ошибку и вылетит, но это не повредит вашей программе.
Возвращаясь к теме нашего кода, Convert.ToInt32 изменяет ввод строки на целое число, чтобы значение можно было сохранить в переменной age. Затем мы снова отправляем входные данные, запрашивая год рождения пользователя. И снова выполнение останавливается, и программа ожидает ввода данных пользователем. Пользователь вводит год рождения, введенная строка преобразуется в целое число с помощью статической функции класса Convert.ToInt32, а затем значение сохраняется в переменной «год рождения».
//Печать пустой строки
Эту строку кода мы добавили для эстетики. Эта строка кода просто выводит пустую строку в программе. Он ничего не делает, кроме как отделяет пользовательский ввод от вывода, который мы собираемся отобразить. Когда вы создаете свои программы, важно думать о пользовательском опыте. Всегда делайте ввод и вывод простыми для понимания пользователем. Когда пользовательский опыт плохой, пользователи находят другие программы, которые легче понять. Юзабилити также должно быть проблемой, когда вы кодируете свою программу. Мы добавляем пустую строку, чтобы пользователю было легко просмотреть вывод консоли, идентифицировать ввод и отделить его от вывода. Наша программа небольшая, но правильное форматирование помогает повысить удобство использования вашей программы.
//Показать данные, которые ввел пользователь
Console.WriteLine("Имя .", name);
Console.WriteLine("Возраст .", age);
Console.WriteLine("Год рождения .", Год рождения);
Вы также можете иметь другие переменные в списке. Они должны быть разделены запятой. Для каждой переменной вы добавляете еще одно число в скобках. Например, если мы добавим переменную age в первую строку кода, возраст будет добавлен после запятой в списке переменных, а строка будет содержать a, чтобы указать, что следует использовать вторую переменную. Помните, что любое значение компьютера начинается с 0, поэтому символы замены также начинаются с 0.
После завершения программы ее можно скомпилировать и запустить из интегрированной среды разработки Visual Studio. В верхнем меню IDE вы видите зеленую стрелку с надписью «Пуск». Щелкните ее, и ваша программа запустится в консоли. Когда вы используете эту кнопку, вы автоматически запускаете программу в отладчике, который является средой тестирования в Visual Studio. Введите ввод при появлении запроса и протестируйте свою программу. Вы даже можете кинуть неверные данные, чтобы увидеть сбой программы. Надлежащее тестирование должно выявить ошибки, включая логические ошибки и ошибки проверки ввода.
Эта простая программа позволяет попрактиковаться в вводе данных пользователем. Помните, что мы пропустили проверку и проверку ошибок. Вам нужно будет добавить закодированную логику, которая определяет, введены ли какие-либо неверные данные, которые могут привести к сбою программы.Немного потренировавшись, вы сможете работать с пользовательским вводом и сохранять его в базе данных или использовать его для создания вычислений и возврата ответа пользователю без каких-либо ошибок.
Некоторая информация относится к предварительной версии продукта, которая может быть существенно изменена до ее выпуска. Microsoft не дает никаких явных или подразумеваемых гарантий в отношении представленной здесь информации.
Читает следующую строку символов из стандартного потока ввода.
Возврат
Следующая строка символов из входного потока или null, если больше нет доступных строк.
Исключения
Произошла ошибка ввода-вывода.
Недостаточно памяти для выделения буфера для возвращаемой строки.
Количество символов в следующей строке больше MaxValue.
Примеры
В следующем примере требуются два аргумента командной строки: имя существующего текстового файла и имя файла, в который будут записываться выходные данные. Он открывает существующий текстовый файл и перенаправляет стандартный ввод с клавиатуры в этот файл. Он также перенаправляет стандартный вывод из консоли в выходной файл. Затем он использует метод Console.ReadLine для чтения каждой строки в файле, заменяет каждую последовательность из четырех пробелов символом табуляции и использует метод Console.WriteLine для записи результата в выходной файл.
Примечания
Метод ReadLine считывает строку из стандартного потока ввода. (Определение линии см. в абзаце после следующего списка.) Это означает, что:
Если стандартным устройством ввода является клавиатура, метод ReadLine блокируется до тех пор, пока пользователь не нажмет клавишу Enter.
Одним из наиболее распространенных применений метода ReadLine является приостановка выполнения программы перед очисткой консоли и отображением на ней новой информации или запрос пользователя на нажатие клавиши Enter перед завершением работы приложения. Следующий пример иллюстрирует это.
Если стандартный ввод перенаправляется в файл, метод ReadLine считывает строку текста из файла. Например, ниже приведен текстовый файл с именем ReadLine1.txt:
В следующем примере используется метод ReadLine для чтения входных данных, перенаправленных из файла. Операция чтения завершается, когда метод возвращает null , что указывает на то, что не осталось строк для чтения.
После компиляции примера в исполняемый файл с именем ReadLine1.exe его можно запустить из командной строки, чтобы прочитать содержимое файла и отобразить его на консоли. Синтаксис:
Строка определяется как последовательность символов, за которой следует возврат каретки (шестнадцатеричное число 0x000d), перевод строки (шестнадцатеричное число 0x000a) или значение свойства Environment.NewLine. Возвращаемая строка не содержит завершающих символов. По умолчанию метод считывает ввод из 256-символьного входного буфера. Поскольку сюда входят символы Environment.NewLine, метод может считывать строки, содержащие до 254 символов. Чтобы прочитать более длинные строки, вызовите метод OpenStandardInput(Int32).
Метод ReadLine выполняется синхронно. То есть он блокируется до тех пор, пока не будет прочитана строка или не будет нажата комбинация клавиш Ctrl+Z (за которой следует Enter в Windows). Свойство In возвращает объект TextReader, который представляет стандартный поток ввода и имеет как синхронный метод TextReader.ReadLine, так и асинхронный метод TextReader.ReadLineAsync. Однако при использовании в качестве стандартного потока ввода консоли TextReader.ReadLineAsync выполняется синхронно, а не асинхронно, и возвращает Task только после завершения операции чтения.
Если этот метод вызывает исключение OutOfMemoryException, позиция средства чтения в базовом объекте Stream увеличивается на количество символов, которые метод смог прочитать, но символы, уже считанные во внутренний буфер ReadLine, отбрасываются. Поскольку положение средства чтения в потоке изменить нельзя, уже прочитанные символы невозможно восстановить, и к ним можно получить доступ только путем повторной инициализации TextReader. Если начальная позиция в потоке неизвестна или поток не поддерживает поиск, базовый поток также необходимо повторно инициализировать. Чтобы избежать такой ситуации и создать надежный код, следует использовать свойство KeyAvailable и метод ReadKey и сохранять считанные символы в предварительно выделенном буфере.
Если нажата комбинация клавиш Ctrl+Z (за которой следует Enter в Windows), когда метод считывает ввод с консоли, метод возвращает значение null . Это позволяет пользователю предотвратить дальнейший ввод с клавиатуры, когда метод ReadLine вызывается в цикле. Следующий пример иллюстрирует этот сценарий.
Читайте также: