Четверг, 18 Апреля 2024, 22:24

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » Delphi/Pascal/Object Pascal » Проблема с паскалем. (Как сделать задержку перед завершением console-приложения)
Проблема с паскалем.
ArtSvetlakovДата: Воскресенье, 06 Января 2013, 12:04 | Сообщение # 1
частый гость
Сейчас нет на сайте
Всем привет)

Учу паскаль по книжке "Песни о паскале". Там задержка в консольных приложениях была реализована командой readln перед самым концом кода (т.е перед end.)
И во всех примерах это прекрасно работало, но вот написал программу там по заданию и вроде всё правильно написал, но задержка не происходит и программа закрывается. И я не успеваю взглянуть на результат.

Подскажите пожалуйста как это исправить или как ещё можно реализовать задержку smile
P.S: Код компилил и в Турбо Паскале и во Фри Паскале: результат один и тот же.

вот сам код:


Сообщение отредактировал ArtSvetlakov - Воскресенье, 06 Января 2013, 12:11
MGD-teamДата: Воскресенье, 06 Января 2013, 12:12 | Сообщение # 2
частый гость
Сейчас нет на сайте
Delay(a)
a - задержка в миллисекундах


ArtSvetlakovДата: Воскресенье, 06 Января 2013, 12:16 | Сообщение # 3
частый гость
Сейчас нет на сайте
Выдает ошибку "Неизвестный идентификатор".
MGD-teamДата: Воскресенье, 06 Января 2013, 12:23 | Сообщение # 4
частый гость
Сейчас нет на сайте
А, сделай
Код
uses crt;
в начале.


karuyДата: Воскресенье, 06 Января 2013, 12:25 | Сообщение # 5
заслуженный участник
Сейчас нет на сайте
Sleep(aValue: Integer);
ArtSvetlakovДата: Воскресенье, 06 Января 2013, 12:55 | Сообщение # 6
частый гость
Сейчас нет на сайте
MGD-team, Ошибку уже не пишет, но задержки всё равно нет. Просто завершается и всё.
karuy,
Цитата (karuy)
Sleep(aValue: Integer);
"Неизвестный идентификатор".

Но я решил проблему. Правда немножко забавным способом biggrin
Вот:

Добавлено (06.01.2013, 12:55)
---------------------------------------------
Глупо наверное, но может это глюки самого паскаля biggrin
Ведь способ, описанный в самом первом сообщении в теме, работал ведь до поры, до времени))

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

Спасибо за помощь smile

Сообщение отредактировал ArtSvetlakov - Воскресенье, 06 Января 2013, 12:44
TimKruzДата: Воскресенье, 06 Января 2013, 16:06 | Сообщение # 7
старожил
Сейчас нет на сайте
Я уже когда-то кому-то в какой-то теме объяснял эту проблему, можно поискать то сообщение в этом разделе. Всё просто и банально, но многие новички этого не понимают сразу. Объясню ещё раз.

ArtSvetlakov, у тебя в коде стоит read(a1,b1,a2,b2), а в конце кода стоит readln. После того, как ты ввёл эти четыре переменные, ты нажал enter, т.е. ввёл символы возврата каретки и перевода каретки на новую строку. Однако процедура read не считывает эти два символа. Зато это делает readln (расшифровка - "read line", т.е. "прочитать строку"), которая считывает всё, включая символы в конце строки. То есть, когда выполнение программы доходит до "пустого" (без аргументов) readln, идущего после (сразу или через N строк - неважно) read, она считывает оставшиеся в буфере ввода символы, которые были введены нажатием enter, но не прочитаны read. И, естественно, если после readln никакого кода больше нет - программа завершается.
Так какое же решение? Решение банально - перед заключительным readln писать не read, а readln, либо в конце программы писать два пустых readln подряд. Ну и вообще, нужно смотреть, где лучше использовать read, а где readln, хотя при вводе данных вручную (из консоли MS-DOS) практической разницы между read и readln нет (всё равно ввод данных завершается нажатием enter, а это провоцирует перевод строки; чтение без перевода строки можно осуществлять функциями keypressed и readkey модуля crt и циклом, но новичку это сделать несколько сложнее, а практическая ценность сомнительна). Но, конечно, при получении данных из, например, файла разница уже есть.

Цитата (MGD-team)
Delay(a)
Цитата (ArtSvetlakov)
Выдает ошибку "Неизвестный идентификатор".
Цитата (ArtSvetlakov)
задержки всё равно нет. Просто завершается и всё.

Процедура delay(миллисекунды) находится в модуле crt и позволяет приостановить выполнение программы на необходимое количество миллисекунд. Однако, действительное время задержки меняется в зависимости от микропроцессора (или чего-то другого, точно не знаю), т.е. delay(1000) на одном компьютере будет давать правильную задержку в 1 секунду, на другом зависнет на 10 секунд, а на третьем задержка будет вообще незаметна для пользователя. Всё из-за того, что TurboPascal разрабатывался относительно давно, а компьютерные технологии меняются очень быстро, поэтому старые методы работают плохо или не работают совсем на современных компьютерах... Поэтому использовать delay нежелательно, если хочешь использовать программу на разных компьютерах (но чисто для своего компьютера подогнать приблизительную задержку всё-таки можно).
Но делать задержку на требуемые N миллисекунд в TurboPascal всё-таки можно; для этого можно, например, с помощью функций получения времени системных часов модуля dos получать системное время в цикле, и выходить из цикла при достижении определённого времени.

Цитата (karuy)
Sleep(aValue: Integer);
Цитата (ArtSvetlakov)
"Неизвестный идентификатор".

Правильно, процедуры sleep вообще нет в Паскале, она заменила delay в Delphi.

Цитата (ArtSvetlakov)
Но я решил проблему. Правда немножко забавным способом

Так тоже можно, но я бы посоветовал использовать конструкцию типа такой:
Код
uses crt;
begin
   repeat
     //полезный код
     writeln('Для выхода нажмите escape, для повторения нажмите любую клавишу...');
   until readkey=#27; //либо так: until readkey<>#32; тогда текст меняется на
   //'для повтора нажмите пробел, для выхода любую другую клавишу...'
end.

Её можно всячески усложнять, добавляя различные условия и переходы, но общая суть одна - вместо завершения можно пройтись по программе снова, не перезапуская её (полезно при тестировании). Функция readkey считывает один символ из буфера клавиатуры, если буфер пуст - ждёт, когда пользователь нажмёт любую кнопку. Естественно, в самом коде следует использовать readln (либо очищать буфер вручную, вызовом readkey), чтобы при проверке условия until... буфер клавиатуры был пуст и, тем самым, возникло ожидание нажатия. Символ #27 - это клавиша escape, символ #32 - пробел, символ #13 - enter (именно так, это виртуальный код клавиши, помещаемый в буфер клавиатуры). Ну с остальными символами, если хочешь, сам разберёшься, на эту тему куча примеров в разных книгах по Паскалю есть.

P.S. Писать program... совсем не обязательно. Она может быть нужна, например, если программа вызывается другой программой на TurboPascal (тогда это название должно совпадать с названием файла программы).


ArtSvetlakovДата: Воскресенье, 06 Января 2013, 16:32 | Сообщение # 8
частый гость
Сейчас нет на сайте
О, спасибо огромное, TimKruz!!! smile Про эти тонкости с read и readln я вообще не знал, так как паскаль толком осваивать начал дня 4 назад biggrin
Форум игроделов » Программирование » Delphi/Pascal/Object Pascal » Проблема с паскалем. (Как сделать задержку перед завершением console-приложения)
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг