Любые данные, которые считываются программой, должны сначала храниться в переменной. Например, программа, которая считывает число студентов со входа, должна сохранить эту информацию в переменной. Тип этой конкретной переменной может быть int.
Как мы уже видели в предыдущей главе, мы не должны печатать стандартный вывод (stdout) на выходе, потому что это подразумевается. Кроме того, то, что должно быть напечатано указывается в качестве аргумента. Так, записи (studentCount) достаточно, чтобы вывести значение studentCount. Подведем итог:
поток: stdout
операция: write
данные: значение переменной studentCount
цель: окно консоли
Обратной write является readf; она считывает данные со стандартного ввода. «f» в её названии происходит от «форматированный», ибо, строка, которую она считывает, должна быть представлена в определенном формате. Мы также видели в предыдущей главе, что стандартный входной поток это stdin.
В случае чтения, один кусочек пазла до сих пор отсутствует: где хранить данные? Подведем итог:
поток: stdin
операция: readf
данные: некоторая информация
цель: ?
Место, где должны храниться данные, задается адресу переменной. Адрес переменной — это точное расположение в памяти компьютера, где хранится её значение. В D символ &, который набирается перед именем переменной — это её адрес. Например, адресом studentCount является &studentCount.
Здесь &studentCount можно прочитать как «адрес studentCount», это и есть недостающий ответ на вопрос выше:
поток: stdin
операция: readf
данные: некоторая информация
цель: расположение переменной studentCount
Ввод & перед именем означает указатель на то, что представляет данное имя. Эта концепция является основой ссылок и указателей, про которые мы узнаем в последующих главах.
Оставим разъяснение одной особенности в использовании readf на будущее; на данный момент, давайте принимать, как правило, что первый аргумент readf должен быть «%s«:
readf("%s", &studentCount);
Примечание: Как объясним ниже, в большинстве случаев также должен быть пробел: » %s«.
«%s» указывает что данные автоматически должны быть преобразованы таким образом, чтобы подходить для типа данной переменной. Например, когда символы ‘4‘ и ‘2‘ считываются в переменную типа int, они будут преобразованы в целочисленное значение 42.
Программа ниже просит пользователя ввести количество студентов. Вы должны нажать клавишу Enter после ввода числа:
import std.stdio; void main() { write("How many students are there? "); /* * Определение переменной, которая будет использоваться для * хранения информации, которая считывается со входа. */ int studentCount; // Сохранение входных данных для данной переменной readf("%s", &studentCount); writeln("Got it: There are ", studentCount, " students."); }
Без подробностей про символы пробела
Даже клавиша Enter, что мы нажимаем после ввода данных, хранится в виде специального кода и помещается в поток стандартного ввода. Это полезно для программ при проверке была ли введена информация в одну строку или в несколько.
Хотя это иногда и полезно, такие специальные коды в основном не важны для программы и должны быть отфильтрованы со входа. В противном случае они блокируют вход и не дают прочитать другие данные.
Чтобы увидеть эту проблему в программе, давайте считаем также количество преподавателей со входа:
void main() { write("How many students are there? "); int studentCount; readf("%s", &studentCount); write("How many teachers are there? "); int teacherCount; readf("%s", &teacherCount); writeln("Got it: There are ", studentCount, " students", " and ", teacherCount, " teachers."); }
К сожалению, теперь программа застревает при чтении второго уровня:
How many students are there? 100
How many teachers are there? 20
← The program gets stuck here
Хотя пользователь вводит количество преподавателей как 20, специальный код (s), представляющий клавишу Enter, которая была нажата после ввода 100, прежнему во входном потоке и блокирует новый Enter. Символы, которые появились во входном потоке похожи на следующее:
100[EnterCode]20[EnterCode]
Первая [EnterCode] блокирует последующий Enter.
Решение заключается в использовании пробела перед %s. Это указывает, что [EnterCode], который появляется перед чтением число преподавателей не важен: « %s«. Пробелы в формате строк используются для чтения и игнорирования ноля и более невидимых символов, которые могут появляться на входе. Такие символы включают сам пробел, код(s), представляющий клавишу ввода, и т.д., и называются символами пробела.
Как правило, вы можете использовать « %s» для каждых данных, считанных со входа. Программа, представленная выше работает, как ожидалось, со следующими изменениями:
// ... readf(" %s", &studentCount); // ... readf(" %s", &teacherCount); // ...
Выход:
How many students are there? 100
How many teachers are there? 20
Got it: There are 100 students and 20 teachers.
Источник: http://ddili.org/ders/d.en/input.html