Готовый перевод Programming in D / Перевод: Reading from the Standard Input / Чтение со стандартного ввода
Ddoc
$(DERS_BOLUMU $(IX ввод) Чтение со стандартного ввода)
$(P
Все что считывает программа должно быть куда-то сохранено.
К примеру, программа считывающая количество учеников в классе, должна сохранить эту информацию в какую-нибудь переменную.
Типом этой переменной мог бы быть $(C int).
)
$(P
Как мы помним из предыдущей главы, если нужно что-то отправить на вывод, вовсе необязательно писать $(C stdout).
К тому-же, то что должно быть распечатано передается аргументом.
И так, чтобы распечатать значение, хранящееся в $(C studentCount), достаточно написать $(C write(studentCount)).
Подведем итог:
)
$(MONO
поток: stdout
действие: write
данные: значение переменной studentCount
получатель: обычно это окно терминала
)
$(P
$(IX readf) $(C write) записывает в стандартный вывод; $(C readf) обратная ей функция, она читает из стандартного ввода.
Буква "f" в конце названия, от английского слова "formatted" означающего - в каком-либо заранее определенном виде; то что считывает эта функция, всегда должно соответствовать какому-либо шаблону.
)
$(P
Из предыдущей главы нам известно что $(C stdin) это стандартный поток ввода.
)
$(P
При чтении данных не хватает одной части головоломки - куда же сохранять прочитанные данные.
Подведем итог:
)
$(MONO
поток: stdin
действие: readf
данные: что-либо
получатель: ?
)
$(P
Куда будут сохранены прочитанные данные определяется адресом переменной.
Адрес переменной - это то место в памяти, в котором хранится значение переменной.
)
$(P
$(IX &, получение адреса) Знак $(C &) написанный перед именем означает адрес того что представляет имя.
К примеру, $(C &studentCount) это адрес переменной $(C studentCount).
Так $(C &studentCount) можно прочесть как "адрес $(C studentCount)" - это и есть искомая часть головоломки:
)
$(MONO
поток: stdin
действие: readf
данные: что-либо
получатель: место в памяти, на которое указывает переменная studentCount
)
$(P
Написание знака $(C &) перед каким-либо именем означает $(I указание) на то что представляется этим именем.
Это основа того что называется ссылки и указатели. Мы поговорим об этом в других главах.
)
$(P
Позже я расскажу подробней про $(C readf). А пока будем считать, что первым аргументом $(C readf) должна быть строка $(STRING "%s"):
)
---
readf("%s", &studentCount);
---
$(P
$(C readf) вполне может работать и без знака $(C &):
)
---
readf("%s", studentCount); // тоже что и в примере выше
---
$(P
Хотя без использования знака $(C &) код лучше и безопасней, все же я продолжу применять $(C readf) к указателям, отчасти для того чтобы подготовить вас к встрече с $(LINK2 /ders/d.en/value_vs_reference.html, ссылками) и $(LINK2 /ders/d.en/function_parameters.html, особыми параметрами функций в виде ссылок).
)
$(P
Строка $(STRING "%s") указывает на то что данные должны быть автоматически преобразованы в значение, соответствующее типу переменной.
Так, при считывании знаков '4' и '2' в переменную типа $(C int), они преобразуются в число 42.
)
$(P
Следующая программа "спрашивает" у пользователя сколько учеников в его классе.
Когда укажите количество учеников, нажмите ENTER:
)
---
import std.stdio;
void main() {
write("Сколько у вас в классе учеников? ");
/* Объявляем переменную для хранения информации
* прочитанной из стандартного ввода. */
int studentCount;
// Сохраняем в нашу переменную данные введенные пользователем.
readf("%s", &studentCount);
writeln("Кол-во учеников: ", studentCount, ".");
}
---
$(H5 $(IX %s и пробельные знаками) $(IX пробельные знаки) Пропуск пробельных знаков)
$(P
Когда мы вводим данные и нажимаем ENTER, в поток $(C stdin) попадают введенные данные и специальный код клавиши ENTER.
Ведь иногда полезно знать каков был ввод - однострочный или многострочный.
)
$(P
Иногда специальные коды полезны, но в основном они нас не интересуют, и потому должны быть отфильтрованы от ввода.
Иначе они $(I заблокируют) ввод, и не дадут прочесть оставшиеся данные.
)
$(P
Что бы увидеть как это бывает, рассмотрим задачу когда нужно прочесть два значения - к ученикам добавить еще и учителей:
)
---
import std.stdio;
void main() {
write("Сколько у вас в классе учеников? ");
int studentCount;
readf("%s", &studentCount);
write("Сколько у вас в классе учителей? ");
int teacherCount;
readf("%s", &teacherCount);
writeln( "Кол-во учеников: ", studentCount, ",",
" кол-во учителей: ", teacherCount, ".");
}
---
$(P
К сожалению, если нужно дважды подряд получить значение типа $(C int), то это код не подойдет:
)
$(SHELL
Сколько у вас в классе учеников? 100
Сколько у вас в классе учителей? 20
$(SHELL_NOTE_WRONG Здесь выброшено исключение)
)
$(P
Когда пользователь ввел число 100 и нажал ENTER, то в поток ввода попало представление клавиши ENTER, и не смотря на то что потом в качестве числа представляющего количество учителей пользователь ввел 20, поток уже заблокирован.
И теперь поток ввода походит вот на что:
)
$(MONO
100$(HILITE [КодКлавишиEnter])20[КодКлавишиEnter]
)
$(P
Код клавиши ENTER что мешает вводу выделен.
)
$(P
И так, чтобы указать что код клавиши ENTER перед числом учителей не важен, нужно поставить знак пробела перед $(STRING %s): $(STRING " %s").
Пробелы в строке формата, указывают на то что нужно отсеять один и более невидимых знаков, что попадают в поток ввода.
К таким знакам относятся сам пробел, коды клавиши ENTER, знак табуляции, и т.п., а называются они $(I пробельные знаки) $(I (whitespace characters)).
)
$(P
При чтении из ввода, почти для всех данных можно писать $(STRING " %s").
Вот что нужно поменять чтобы программа заработала как надо:
)
---
// ...
readf(" %s", &studentCount);
// ...
readf(" %s", &teacherCount);
// ...
---
$(P
Вывод:
)
$(SHELL
Сколько у вас в классе учеников? 100
Сколько у вас в классе учителей? 20
Кол-во учеников: 100, кол-во учителей: 20.
)
$(H5 Дополнительно)
$(UL
$(LI
$(IX комментарии) $(IX /*) $(IX */) Строки, начинающиеся с последовательности $(COMMENT //) хорошо подходят для однострочных комментариев.
Если нужно написать один комментарий на нескольких строках, то такой комментарий нужно окружить знаками $(COMMENT /*) и $(COMMENT */).
$(P
$(IX /+) $(IX +/) А если нужно закомментировать другой комментарий, то окружите комментарий знаками $(COMMENT /+) и $(COMMENT +/):
)
---
/+
// Комментарий в одну строку
/*
Комментарий занимающий
несколько строк
*/
/+
В таком комментарии могут быть даже вложенные /+ комментарии +/
+/
Комментарий что включает в себя другие комментарии
+/
---
)
$(LI
Многие из пробельных знаков не значимы в исходном коде.
Длинные строки принято разбивать на несколько меньших строк.
Несмотря на это, всю программу можно записать в одну строку с наименьшим количеством пробелов, не нарушая правил языка:
---
import std.stdio;void main(){writeln("Сложно понять!");}
---
$(P
Если в коде мало пробельных знаков, его бывает сложно понимать.
)))
$(PROBLEM_TEK
$(P
Программа "рассчитывает" что вы введете числа, ну а вы введите что-нибудь другое, и убедитесь, что программа не сможет правильно отработает.
))
Macros:
SUBTITLE=Чтение со стандартного ввода
DESCRIPTION=Получение информации со стандартного ввода
KEYWORDS=язык программирования d учебник книга read stdin
MINI_SOZLUK=
Внимание! Этот перевод, возможно, ещё не готов.
Его статус: перевод редактируется
Переведено на Нотабеноиде
http://notabenoid.org/book/71439/398917
Переводчики: dlang
Настройки
Готово:
