Pascal — это высокоуровневый язык программирования, который предоставляет разработчикам возможность программировать в графическом режиме, отслеживать ошибки и тестирование программ. Одной из основных задач при написании программ является чтение и обработка данных. В Pascal для этого используется функция readln(s), которая не всегда работает правильно. В этой статье мы рассмотрим, как избежать ошибок при чтении данных в Pascal с помощью readln(s).
Проблемы, связанные с readln(s)
Проблема с readln(s) заключается в том, что она не всегда может корректно обрабатывать строку, которая передается через параметр s. В частности, если переданная строка содержит пробелы, функция может читать только первое слово и игнорировать остальные. Это приводит к тому, что при попытке считать данные, которые содержат пробелы, программа выдает ошибку или возвращает неправильный результат.
Рассмотрим пример:
Var
s: string;
n: integer;
Begin
readln(s);
readln(n);
End.
Если пользователь вводит «Hello world» в первой строке, а затем «10» во второй строке, программа не сможет правильно прочитать первую строку и вернет ошибку. Также возможна ситуация, когда пользователь случайно добавляет дополнительный перевод строки, который приведет к тому, что программа прочитает неправильную строку.
Другая проблема с readln(s) связана с тем, что она не проверяет правильность ввода данных. Если пользователь вводит значение, которое не соответствует типу данных, указанному в параметре s, программа выдаст ошибку или может работать неправильно.
Как избежать ошибок при чтении данных в Pascal
Существует несколько способов избежать проблем с readln(s), связанных с неправильным чтением и валидацией введенных данных.
Использование функции readln без параметра
Самый простой способ избежать этих проблем — это использование функции readln без параметра. В этом случае, функция будет автоматически считывать ввод пользователя до тех пор, пока не будет нажата клавиша «Enter». Однако, если пользователь случайно введет дополнительный перевод строки или другой символ, программа выдаст ошибку.
Var
s: string;
n: integer;
Begin
readln;
readln(s);
readln(n);
End.
Использование функции trim
Другой способ избежать проблем с readln(s) — это использование функции trim, которая удалит все пробелы из начала и конца строки. Это позволяет избежать проблем с прочтением строки с пробелами.
Var
s: string;
n: integer;
Begin
readln(s);
s := trim(s);
readln(n);
End.
Использование функций валидации данных
Если вы хотите быть уверены, что пользователь вводит правильные данные, можно использовать функции валидации данных. Например, функция val может проверять, соответствует ли введенное значение указанному типу данных. Если значение не соответствует типу данных, программа выдаст ошибку.
Var
s: string;
n: integer;
Begin
readln(s);
if not TryStrToInt(s, n) then
begin
writeln('Invalid input');
end;
End.
Вывод
Функция readln(s) — это удобный способ чтения данных в Pascal, но она имеет определенные проблемы, связанные с прочтением строк с пробелами и проверкой правильности ввода данных. Чтобы избежать этих проблем, вы можете использовать функцию readln без параметра, функцию trim для удаления пробелов или функции валидации данных, такие как val или TryStrToInt.Выберите подходящий способ в зависимости от ваших потребностей в чтении и обработке данных в Pascal.
Модератор: Модераторы
У меня ReadLn — не работает…
Ничего не понимаю…
У меня ReadLn не работает…
Кликните, пожалуйста, у себя Ctrl+клик на ReadLn.
В каком uses находится ReadLn? (для текстовых файлов)
.
-
vitaly_l - долгожитель
- Сообщения: 3333
- Зарегистрирован: 31.01.2012 16:41:41
-
- Профиль
- Сайт
Re: У меня ReadLn — не работает…
bormant » 25.03.2013 13:33:49
ReadLn находится в модуле System, который подключен всегда вне вашего желания.
Поэтому, скорее всего, вы просто перекрыли System.ReadLn одноимённой процедурой в своём коде. Попробуйте в нужном месте вписать System.ReadLn в место ReadLn.
-
bormant - постоялец
- Сообщения: 403
- Зарегистрирован: 21.03.2012 11:26:01
Re: У меня ReadLn — не работает…
vitaly_l » 25.03.2013 14:03:58
bormant писал(а):ReadLn находится в модуле System
Юмор в том что его там нет…
Но ReadLn — начал работать, только я всё равно — не могу посмотреть где он лежит…
т.к. Ctrl+клик на ReadLn не работает.
Assign — показывает.
Reset — показывает.
Close(f); — показывает.
А ReadLn — нет… и простым поиском его в System нет, хотя там: и Assign и Reset и Close…
Но это ужен не актуально, т.к. файл начал считываться и я прочитал то, что хотел и запустил cdecl.
правда только текстовый файл, а не форматированный.
Спасибо Вам.
-
vitaly_l - долгожитель
- Сообщения: 3333
- Зарегистрирован: 31.01.2012 16:41:41
-
- Профиль
- Сайт
Re: У меня ReadLn — не работает…
Sergei I. Gorelkin » 25.03.2013 14:27:49
Readln не существует в виде процедуры, она преобразуется в последовательность вызовов fpc_read_text_sint, fpc_read_text_float и т.д.
-
Sergei I. Gorelkin - энтузиаст
- Сообщения: 1390
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
-
- Профиль
- ICQ
Re: У меня ReadLn — не работает…
vitaly_l » 25.03.2013 14:33:42
Sergei I. Gorelkin писал(а):Readln не существует в виде процедуры, она преобразуется в последовательность вызовов fpc_read_text_sint, fpc_read_text_float и т.д.
Спасибо — большое, добрый Sergei I. Gorelkin
-
vitaly_l - долгожитель
- Сообщения: 3333
- Зарегистрирован: 31.01.2012 16:41:41
-
- Профиль
- Сайт
Re: У меня ReadLn — не работает…
bormant » 25.03.2013 15:02:35
ReadLn не работает
и «не находится реализация ReadLn» — несколько разные вещи. А так да, Read(Ln)/Write(Ln)/Str — compiler magic — операторы/процедуры, созданные надъязыковыми средствами, вместо них компилятор подставляет специфичные случаю реализации.
-
bormant - постоялец
- Сообщения: 403
- Зарегистрирован: 21.03.2012 11:26:01
Re: У меня ReadLn — не работает…
vitaly_l » 25.03.2013 15:14:06
bormant писал(а):и «не находится реализация ReadLn» — несколько разные вещи.
Нет он у меня вначале отказывался работать, т.к. в Вашем примере было ReadLn(f,n); где n: integer; и он выдавал ошибку. когда заменил на String всё стало работать. И тестовые файлы грузятся и cdecl работает. А вот мои файлы, я пока ещё не дешифровал…
Но зато благодаря Вам понял систему программирования того программиста который писал модуль.
Теперь пытаюсь понять как его модуль дешифровал форматированный файл…
Самое обидное, что модуль возможно не работает из-за несовместимости или не того порядка в инициализации uses’ов…
/
-
vitaly_l - долгожитель
- Сообщения: 3333
- Зарегистрирован: 31.01.2012 16:41:41
-
- Профиль
- Сайт
Re: У меня ReadLn — не работает…
Alex2013 » 03.04.2013 13:32:50
Текстовые файлы лучше всего читать-писать через TStringList или если читается только часть файла через TFileStream
А кроме того с ошибками в/в через исключения работать надежнее
Что-то вроде …
- Код: Выделить всё
Function ReadFromFile (Fn:String; FilePos,Size :Longint):string;
Var
Data:String;
F:TFileStream;
I:Longint;
begin
Data:='';
if FileExists(FN) then begin
F:=TFileStream.Create(FN,fmOpenRead);
try
if FilePos+Size<=F.Size then
begin
f.seek(FilePos,soFromBeginning);
For I:=1 to Size do
begin
data:=data ;
f.Read(data[i],1);
end;
end
finally
f.free;
end;
ReadFromFile:=Data;
end
end;
- Alex2013
- долгожитель
- Сообщения: 2712
- Зарегистрирован: 03.04.2013 11:59:44
Вернуться в Lazarus
Кто сейчас на конференции
Сейчас этот форум просматривают: Google [Bot] и гости: 13
18 / 18 / 0 Регистрация: 19.11.2010 Сообщений: 106 |
|
1 |
|
19.11.2010, 21:15. Показов 15552. Ответов 9
Добрый день.
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
19.11.2010, 21:15 |
Ответы с готовыми решениями: Почему Read работает как Readln? (ide PascalABC.NET 3.10 build 1200) Не работает Readln Readln Readln 9 |
189 / 185 / 54 Регистрация: 23.10.2010 Сообщений: 1,335 |
|
19.11.2010, 21:18 |
2 |
думаю проблема может быть просто не в readln))) Не по теме: Иногда бывало что-то похожее, просто добавлял дублирующий readln,readln
0 |
18 / 18 / 0 Регистрация: 19.11.2010 Сообщений: 106 |
|
19.11.2010, 21:24 [ТС] |
3 |
а в чем тогда?
0 |
Почетный модератор 64288 / 47587 / 32739 Регистрация: 18.05.2008 Сообщений: 115,181 |
|
19.11.2010, 21:25 |
4 |
А какой у Вас Паскаль? Не АВС?
0 |
189 / 185 / 54 Регистрация: 23.10.2010 Сообщений: 1,335 |
|
19.11.2010, 21:25 |
5 |
ну я точно сказать не могу))) я не участвую в битве экстрасенсов, а вообще говорю попробуй поставить второй readln
1 |
18 / 18 / 0 Регистрация: 19.11.2010 Сообщений: 106 |
|
19.11.2010, 21:30 [ТС] |
6 |
О, спасиб, 2-е readln помогло. Раньше другой Паскаль стоял, первый раз такое вижу.
0 |
Почетный модератор 64288 / 47587 / 32739 Регистрация: 18.05.2008 Сообщений: 115,181 |
|
19.11.2010, 21:32 |
7 |
Вероятно ранее в коде было read(); поэтому требуется 2 readln;
1 |
80 / 82 / 36 Регистрация: 20.11.2009 Сообщений: 326 |
|
19.11.2010, 21:34 |
8 |
есть на самом деле этому объяснение… ввод элементов массива вы заканчиваете нажатием клавиши Энтер, ее компьютер и трактует как тот самый клик под readln. Объяснил настолько доступно насколько мог, на самом деле жизнь чуть более сложная штука.
0 |
18 / 18 / 0 Регистрация: 19.11.2010 Сообщений: 106 |
|
19.11.2010, 21:38 [ТС] |
9 |
так после ввода массива происходило еще и упорядочивание массива , потом вывод новой псоледовательности, потом строчка «Программу составил» и только потом уже конечный readln
0 |
189 / 185 / 54 Регистрация: 23.10.2010 Сообщений: 1,335 |
|
20.11.2010, 03:59 |
10 |
есть на самом деле этому объяснение… ввод элементов массива вы заканчиваете нажатием клавиши Энтер, ее компьютер и трактует как тот самый клик под readln. Объяснил настолько доступно насколько мог, на самом деле жизнь чуть более сложная штука. не соглошусь. Вообще на сколько мне удалось углубицо в паскале, на столько я уверился, что он слишком виндузирован. Под ubuntu мне так и не удалось привязать его к Lazarus (там чёт с версией компилятора FPC не то было). В Xcode бывают такие случаи, что просто вылетает эрор на первой строке (где program), спасает лишь создание нового проекта. С повторным ридлн возникали про ещё задолго до массивов, на стадии изучения циклов. На вопрос а нафиг, препод отвечал хз, НО РАБОТАЕТ! Добавлено через 1 минуту
Вероятно ранее в коде было read(); поэтому требуется 2 readln; нас препод долбит с оформлением, я всегда использую writeln();read(); типа на одной строке, но только 1/30 нужен повторный.
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
20.11.2010, 03:59 |
Помогаю со студенческими работами здесь Функция readln Вопрос:… Оператор Readln Readkey и Readln ReadLn и строки Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 10 |
Using the Free Pascal IDE, I have some problems with console IO under Windows.
When I use Writeln the cursor doesn’t move to the next line and is staying at the end of the written line. So if I press Enter instead of moving to the next line the cursor goes to the beginning of the current line. And if I use Readln after Writeln new characters that I enter are displayed instead of the characters that were written with Writeln.
When I use Readln to enter string I have next problem. If I enter some string, use backspace to delete characters and enter other characters after that, Readln return to program string that includes backspace symbols and deleted characters.
I guess this is Windows problem, but I have no ideas.
asked Dec 12, 2018 at 13:30
3
It looks as if you have run into a (known) problem with the Free Pascal IDE on Windows 10. This happens to console programs started from that IDE. There is no fix, and no workaround (well, there is one: use unit Crt
). It has other issues as well.
Just try another IDE, e.g. Lazarus.
Note that your program will run fine if started standalone. But not when started from the FPC IDE.
answered Dec 12, 2018 at 18:44
Rudy VelthuisRudy Velthuis
28.4k5 gold badges46 silver badges92 bronze badges
1
Вот ещё довод в пользу решения этой проблемы.
source.pas (https://ideone.com/itdAqx):
var
k: longint;
begin
readln(k);
writeln(2*k);
end.
Запускаем с перенаправлением ввода-вывода:
source.exe <input.txt >output.txt
Если в файле input.txt было только число без следующего за ним перевода строки, то программа, скомпилированная Pascal ABC, зависнет навечно, а при компиляции через Turbo или Free Pascal — завершится успешным выводом в output.txt правильного ответа.
Это неожиданное отличие в поведении Pascal ABC сильно затрудняет автоматизированное тестирование написанных на нём решений.
Например, мы недавно добавили поддержку компилятора Pascal ABC на образовательном портале http://dl.gsu.by, но оказалось, что теперь в некоторых задачах не проходят по времени авторские решения.
В таких случаях помогает вручную добавить недостающие переводы строки в конце проблемных тестов. Но вручную так мигрировать множество задач слишком затратно, а автоматизированно опасно, т.к. в некоторых случаях с нечисловым вводом лишний перевод строки в тестах может всё поломать.
Надеюсь, проблему удастся разрешить внутри readln в Pascal ABC, приведя её в соответствие с остальными реализациями Паскаля.
Необходимо трактовать EOF точно так же как и EOL.