• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

    Если вы у нас впервые, загляните на страницу о форуме и правила – там коротко описано, как задать вопрос так, чтобы быстро получить ответ. Чтобы создавать темы и писать сообщения, сначала зарегистрируйтесь, а затем войдите под своим логином.

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

Паскаль пропускает оператор ввода строки

  • Автор темы Автор темы MrSTEP
  • Дата начала Дата начала

MrSTEP

一步一步地会&#
Почётный участник
Регистрация
9 Май 2009
Сообщения
10,939
Реакции
225
Баллы
63
Паскаль пропускает оператор ввода строки

Написал программу, задание:
В файле хранится информация о каждом студенте группы: фамилия и оценки по трем предметам. Переписать эти данные в другой файл записей, исключая сведения о неуспевающих студентах.
Код:
uses crt;
type student=record
      surname:string;
      mark:array [1..3] of 2..5;
     end;
     gr=array[1..20] of student;
var f,nf:file of gr;
    group,goodgroup:gr;
    i,j,n:integer;
begin clrscr;
      write ('Input number of students (1..20): ');
      readln (n);
      clrscr;
      assign (f, 'group.dat');
      for i:=1 to n do begin [COLOR="Blue"]{1}[/COLOR]
          writeln;
          writeln ('Input information about ', i, ' student');
          with group[i] do begin
               write ('Surname: ');
               readln (surname); [COLOR="#0000ff"]{2}[/COLOR]
               write ('Student's marks by session (Math Physics InfTechnologies): ');
               read (mark[1], mark[2], mark[3]);
          end;
      end;
      rewrite(f);
      write (f, group);
      close (f);
      assign (nf, 'goodgroup.dat');
      rewrite (nf);
      clrscr;
      writeln ('Good students:');
      for i:=1 to n do begin
          with group[i] do begin
               if (mark[1]>=3)and(mark[2]>=3)and(mark[3]>=3) then begin
                  inc(j,1);
                  goodgroup[j]:=group[i];
                  write (goodgroup[j].surname, ' ');
               end;
          end;
      end;
      write (nf, goodgroup);
      close(nf);
      readkey;
end.
так все в порядке, но... первый шаг счетчика {1}. Все операторы ввода-вывода работают нормально. второй шаг - пропускается оператор {2}. То есть на экране видно следующее:
Input information about 2 student
Surname: Student's marks by session (Math Physics InfTechnologies):
Делалось в Turbo Pascal 7.0, пробовал в Borland Pascal, на другом ПК - все так же. Создал в делфи консольное приложение, скорировал туда этот код, подправил.. То же самое. В чем дело?
 
Очень просто - во второй после {2} строке замените read на readln, и всё пойдет.
Но вот чего я никак не могу понять - это как у Вас проходит вывод сообщения Student's marks by session... Дело в том, что у меня, как только трансляция доходит до апострофа в слове Student's, как транслятор полагает, что строка завершена, и, не обнаружив дальше ни запятой, ни закрывающей скобки, тут же рапортует об ошибке (что, по-моему, естественно). А Вам-то как удалось такой фокус-покус провернуть (мне пришлось заменить Student's на Student"s)?
 
а, это :) простое раздолбайство.. немного изменил данную строку перед отправкой на форум, и не заметил, что использовал такой апостроф. В оригинале строка выглядела примерно так: "Marks of this student...", следовательно, проблем при компиляции не было
 
Спасибо тебе, Владимир, все заработало.. но как это связано?
 
Спасибо тебе, Владимир, все заработало.. но как это связано?

Знаешь... поскольку я - самоучка, отвечу несколько непрофессионально. По моему опыту, оператор read - это вообще "плохой" оператор, в том смысле, что нельзя оставлять эту операцию "подвешенной": идут всякие глюки. То есть его можно (и нужно) использовать, например, в цикле чтения элементов строки матрицы, но завершать любое чтение нужно ТОЛЬКО оператором readln. Тогда глюков не будет. Как-то так.
 
хм, ну я тоже стараюсь его не юзать. но здесь... {минутный завис по поводу кода} ступил, когда написал его. все равно, считались бы все значения с одной строки, а потом перекинуло курсор на следующую. В общем, все нормально, спасибо :)
 
С помощью операторов read и readln можно читать данные из текстового файла, но делать это нужно с осторожностью.
Оператор read считывает данные до разделителя, разделителем считается пробел, табуляция или конец строки (для чисел), при этом указатель файла остается перед концом строки.
readln считывает строку целиком и ставит указатель файла после символа конца строки.
Отсюда следует, что если при чтении текстового файла дважды вызвать read подряд, произойдет следующее: первый read дойдет до конца строки и остановится там, второй read начнет читать данные, но в качестве данных считает тот же конец строки и остановится на том же месте, ничего не считав.
Таким образом, read при чтении из текста подходит, если нужно читать числа, записанные в несколько колонок через разделитель (пробел или табуляцию).
При этом, после каждой операции чтения следует проверять, не повстречался ли в файле конец строки (функция eoln()) и если повстречался, перейти на следующую, с помощью вызова readln.
При этом, читать строки с помощью read нельзя, для этого существует readln.
Это описание соответствует тому, что описано в руководстве к очень старой версии Паскаля. Современные компиляторы могут вести себя неправильно.
 
Ну да, именно так. Вот и получается то, что я описал по-простому.:)
 
Нам примерно такое объясняли, но несколько проще и короче. Теперь лучше понял их суть
 
Назад
Сверху