Чтение со стандартного ввода [перевод]

Любые данные, которые считываются программой, должны сначала храниться в переменной. Например, программа, которая считывает число студентов со входа, должна сохранить эту информацию в переменной. Тип этой конкретной переменной может быть 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

Bagomot

Эколог, почти программист-самоучка, мучаю майнкрафт.

Добавить комментарий