IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> работа с файлами, Ошибка при чтении файла
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 8
Пол: Женский
Реальное имя: Катерина

Репутация: -  0  +


Помогите пожалуйста! Как исправить ошибку? Не могу понять, как её исправить, подскажите, очень-очень надо!.. Программа по работе с данными из таблицы. Данные хранятся в текстовом файле(прикреплён к сообщению, см ниже).
Код
program TABLIZA;
uses crt;
const
   p_menu:array [1..7] of string=('-Чтение данных из файла   ',
                                  '-Просмотр входной таблицы',
                                  '-Добавление записей',
                                  '-Удаление записей        ',
                                  '-Обработка и просмотр данных',
                                  '-Сохранение данных в файл',
                                  '-Выход                    ');

type
vhod_t=record                     {входная таблица}
   number:byte;
   FIOdir:string[15];
   FIOen:string[15];
   plan:real;
   fact:real;
end;

vyhod_t=record                     {выходная таблица}
   number:integer;
   FIOdir:string[15];
   FIOen:string[15];
   plan:real;
   fact:real;
   otklon:real;
end;



ukaz=^spisok;                      {список}
spisok=record
  inf:vhod_t;
  next:ukaz;
  end;

  ukaz1=^spisok1;
  spisok1=record
  inf:vyhod_t;
  next:ukaz1;
  end;


var
file_in:file of vhod_t;         {входной и выходной файлы}
file_out:file of vyhod_t;
NewL,nach,kon,vremen:ukaz;
NewE,nach1:ukaz1;
nomermenu, year:integer;
vh_name, vyh_name:string[20];
vh_t:vhod_t;
vyh_t,vyh_t1:vyhod_t;

procedure MENU(var nomermenu:integer);
var x,y,i:integer;
c:char;
begin
x:=28;
y:=1;
gotoXY(x,8);
textcolor(13);
writeln('   Выберите пункт меню:   ');
textcolor(3);
for i:=1 to 7 do begin
gotoXY(x,i+8);
writeln(p_menu[i]);
end;
textcolor(4);
gotoXY(x,y+8);
writeln(p_menu[y]);
while true do
begin
c:=readkey;
case ord(c) of
   80:if y<7 then y:=y+1;
   72:if y>1 then y:=y-1;
   13:break;
end;
gotoXY(x,8);
textcolor(13);
writeln('   Выберите пункт меню:   ');
textcolor(3);
for i:=1 to 7 do begin
gotoXY(x,i+8);
writeln(p_menu[i]);
end;
textcolor(4);
gotoXY(x,y+8);
writeln(p_menu[y]);
end;
nomermenu:=y;
textcolor(white);
end;

procedure readfile(vh_name:string);
    begin
writeln('Введите путь к входному файлу');
readln(vh_name);

assign(file_in,vh_name);
reset(file_in);
if IOResult>0 then begin
writeln('Ошибка открытия файла');
exit;
end;
read(file_in,vh_t);    {=================ЗДЕСЬ ВЫДАЁТСЯ ОШИБКА===============}
New(NewL);
NewL^.inf.number:=vh_t.number;
NewL^.inf.FIOdir:=vh_t.FIOdir;
NewL^.inf.FIOen:=vh_t.FIOen;
NewL^.inf.plan:=vh_t.plan;
NewL^.inf.fact:=vh_t.fact;
NewL^.next:=nil;
nach:=NewL;
kon:=NewL;
reset(file_in); read(file_in,vh_t);
while not EOF(file_in) do begin
read(file_in,vh_t);
New(NewL);
NewL^.inf.number:=vh_t.number;
NewL^.inf.FIOdir:=vh_t.FIOdir;
NewL^.inf.FIOen:=vh_t.FIOen;
NewL^.inf.plan:=vh_t.plan;
NewL^.inf.fact:=vh_t.fact;
NewL^.next:=nil;
kon^.next:=NewL;
kon:=NewL;
end;
end;

procedure prosmotr_vhod(nach:ukaz);
var x,y,i,n,t:integer;
c:char;
begin
writeln('Просмотр таблицы':70);
x:=1;y:=1;
{gotoxy(x,y);}
writeln('|--------|---------------|---------------|--------------|-----------|');
writeln('| Номер  | ФИО директора |  ФИО главного | израсходовано| фактически|');
writeln('|        |               |  энергетика   |   тыс КВт*ч  | тыс КВт*ч |');
n:=0;
vremen:=nach;
  while vremen<>nil do
begin

writeln('|--------|---------------|---------------|--------------|-----------|');
writeln('|',vremen^.inf.number:6,'|',vremen^.inf.FIOdir:15,'|',vremen^.inf.FIOen:15,'|',vremen^.inf.plan:4,'|',
vremen^.inf.fact:4,'|');
vremen:=vremen^.next;
n:=n+1;
end;
writeln('|--------|---------------|---------------|--------------|-----------|');

while true do begin
c:=readkey;
t:=ord(c);
if t= 13 then break;

if t=8 then begin Delline;   delline;end;
if t=  72 then begin
                    if y>1 then y:=y-2;
                    gotoxy(x,y);
                    if (y=1) then
                      vremen:=nach^.next;
                        while vremen<>nil do
begin

writeln('|--------|----------------|---------------|--------------|----------|');
writeln('|',vremen^.inf.number:6,'|',vremen^.inf.FIOdir:15,'|',vremen^.inf.FIOen:15,'|',vremen^.inf.plan:4,'|',
vremen^.inf.fact:4,'|');
vremen:=vremen^.next;
n:=n+1;
end;

                end;
if t=80 then begin
                      if y<n then y:=y+2;
                      gotoxy(x,y);


              end;


end;


end;

procedure dobavlenie( var kon:ukaz;var nach:ukaz);
begin
writeln('Введите номер завода');
readln(vh_t.number);
writeln('Введите ФИО директора');
readln(vh_t.FIOdir);
writeln('Введите ФИО главного энергетика');
readln(vh_t.FIOen);
writeln('Израсходовано энергии по плану');
readln(vh_t.plan);
writeln('Израсходовано энергии фактически');
readln(vh_t.fact);
New(NewL);
NewL^.inf.number:=vh_t.number;
NewL^.inf.FIOdir:=vh_t.FIOdir;
NewL^.inf.FIOen:=vh_t.FIOen;
NewL^.inf.plan:=vh_t.plan;
NewL^.inf.fact:=vh_t.fact;
NewL^.next:=nil;
if kon=nil then
nach:=NewL
else
kon^.next:=NewL;
kon:=NewL;
write(file_in,vh_t);
end;

procedure udalenie;         {удаление из начала списка}
var
temp:ukaz;
begin
if nach<>nil then
begin
temp:=nach;
nach:=nach^.next;
dispose(temp);
if nach=nil then
kon:=nil;
end;
end;

procedure obrabotka_prosmotr;
var sump,sumf,sumo:real;
sred:real;
kon:ukaz1;
begin
sump:=0;
sumf:=0;
sumo:=0;
nach1:=nil;
kon:=nil;
seek(file_in,0);
writeln('Отклонение факта от плана (со знаком)');
writeln('|--------|---------------|---------------|--------------|-----------|-----------|');
writeln('| Номер  | ФИО директора |  ФИО главного | израсходовано| фактически| отклонение|');
writeln('|        |               |  энергетика   |   тыс КВт*ч  | тыс КВт*ч | тыс КВт*ч |');

read(file_in,vh_t);
New(NewE);
NewE^.inf.number:=vh_t.number;
vyh_t1.number:=NewE^.inf.number;
NewE^.inf.FIOdir:=vh_t.FIOdir;
vyh_t1.FIOdir:=NewE^.inf.FIOdir;
NewE^.inf.FIOen:=vh_t.FIOen;
vyh_t1.FIOen:=NewE^.inf.FIOen;
NewE^.inf.plan:=vh_t.plan;
vyh_t1.plan:=NewE^.inf.plan;
NewE^.inf.fact:=vh_t.fact;
vyh_t1.fact:=NewE^.inf.fact;
writeln('|--------|---------------|---------------|--------------|-----------|-----------|');
writeln('|',NewE^.inf.number:6,'|',NewE^.inf.FIOdir:15,'|',NewE^.inf.FIOen:15,'|',
NewE^.inf.plan:4,'|',NewE^.inf.fact:4,'|',NewE^.inf.otklon:5,'|');



while not EOF(file_in) do  begin
read(file_in,vh_t);
if((vh_t.plan>0)and(vh_t.fact>0)) then begin
New(NewE);
NewE^.inf.number:=vh_t.number;
vyh_t1.number:=NewE^.inf.number;
NewE^.inf.FIOdir:=vh_t.FIOdir;
vyh_t1.FIOdir:=NewE^.inf.FIOdir;
NewE^.inf.FIOen:=vh_t.FIOen;
vyh_t1.FIOen:=NewE^.inf.FIOen;
NewE^.inf.plan:=vh_t.plan;
vyh_t1.plan:=NewE^.inf.plan;
NewE^.inf.fact:=vh_t.fact;
vyh_t1.fact:=NewE^.inf.fact;
writeln('|--------|---------------|---------------|--------------|-----------|-----------|');
writeln('|',NewE^.inf.number:6,'|',NewE^.inf.FIOdir:15,'|',NewE^.inf.FIOen:15,'|',
NewE^.inf.plan:4,'|',NewE^.inf.fact:4,'|',NewE^.inf.otklon:5,'|');

kon:=NewE;
NewE^.next:=nil;

while kon<>nil do begin
kon^.inf.otklon:=kon^.inf.plan-kon^.inf.fact;
kon:=kon^.next;
sump:=sump+kon^.inf.plan;
sumf:=sumf+kon^.inf.fact;
sumo:=sumo+kon^.inf.otklon
end;

writeln('|--------|---------------|---------------|--------------|-----------|-----------|');
writeln('|',NewE^.inf.number:6,'|',NewE^.inf.FIOdir:15,'|',NewE^.inf.FIOen:15,'|',
NewE^.inf.plan:4,'|',NewE^.inf.fact:4,'|',NewE^.inf.otklon:5,'|');
end;
end;
writeln('|--------|---------------|---------------|--------------|-----------|-----------|');
if (sump<=0) or (sumf<=0) then  begin writeln('введены неверные значения');readln;exit;

writeln('|        |               |               |',sump:4:2,'|',sumf:5:2,'|',sumo:5:2,'|');
writeln('|--------|---------------|---------------|--------------|-----------|-----------|');
end;
readln;
end;

procedure save_file(var vyh_t1,vyh_t:vyhod_t);
begin
assign(file_out,'d:\vyhodtable.txt');
  rewrite (file_out);
write(file_out,vyh_t1);
write(file_out,vyh_t);
end;

begin
nach:=nil;
kon:=nil;
while true do begin
clrscr;
menu(nomermenu);
case nomermenu of
1:begin clrscr;readfile(vh_name); end;
2: begin clrscr; prosmotr_vhod(nach);  end;
3: begin clrscr; dobavlenie(kon,nach);end;
4:begin clrscr;udalenie;end;
5:begin clrscr;obrabotka_prosmotr;end;
6:begin clrscr;save_file(vyh_t1,vyh_t);end;
7:break;
end;
end;
end.

Прикрепленный файл  vhodt.txt ( 926 байт ) Кол-во скачиваний: 280

Прикрепленный файл  KURSOVIC.PAS ( 8.08 килобайт ) Кол-во скачиваний: 321


Сообщение отредактировано: IchLiebeDich -


--------------------
Dear god, make everyone die. Amen.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2





Группа: Пользователи
Сообщений: 8
Пол: Женский
Реальное имя: Катерина

Репутация: -  0  +


Чуствую, ответа мне не дождаться...


--------------------
Dear god, make everyone die. Amen.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Зайди попозже, завтра..
обещаю посмотреть smile.gif
немного пугает взгляд.. smile.gif
извини, размер тоже иногда важен, сама понимаешь... smile.gif


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата
Как исправить ошибку?
Ты же описываешь входной файл, как file of vhod_t, а читать пытаешься из текстового... То, что там содержится вся нужная информафия еще ничего не значит... Формат не тот...

Вот смотри: размер структуры vhod_t = 43 байта, размер файла = 926 байт, 926 на 43 НАЦЕЛО не делится, а ведь
read(file_in,vh_t);
будет пытаться читать данные блоками по 43 байта из файла целое число раз, при нехватке данных программа просто вылетит и все smile.gif

Выходов у тебя два: первый - работать с текстовым, а не типизированным файлом, второй - при старте программы (или где нибудь в меню сделать соответствующий пункт) вызывать процедуру корректировки, которая будет читать данные из текстового файла и записывать в типизированный...

Кстати, у тебя есть 2 неточности (которые могут быть проблематичны, если не сейчас, то потом):

1) byte хранит значения 0 - 255, а у тебя в файле присутствуют бОльшие значения...
2) при записи вещественных чисел используется не запятая, а точка...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5





Группа: Пользователи
Сообщений: 8
Пол: Женский
Реальное имя: Катерина

Репутация: -  0  +


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

а как это сделать? blink.gif


--------------------
Dear god, make everyone die. Amen.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гуру
*****

Группа: Пользователи
Сообщений: 1 220
Пол: Мужской

Репутация: -  16  +


Цитата(IchLiebeDich @ 2.12.2006 6:53) *

а как это сделать? blink.gif

Определить текстовый файл:
var
file_in_text:text;
Читать из него построчно:
Realdn(file_in_text,s);
Разбить полученную строку на части ф-цией GetWords
присвоить полям записи - полученные ф-цией значения
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(IchLiebeDich @ 2.12.2006 6:53) *

а как это сделать? blink.gif

Думаю, volvo на этот раз пошутил.. smile.gif. Нет смысла делать такую процедуру и писать на диск дополнительный файл (для которого, при нормальных рабочих размерах нормальной рабочей базы может и не хватить места smile.gif). И к тому же та процедура все равно будет делать именно то, что тебе надо в основном коде - так почему бы не вставить этот код прямо туда?.. При желании можно иметь возможность записывать (и читать) два типа файлов: текстовой и типизированный. Преимуществ одного перед другим я не вижу, кроме возможности редактировать текст в другом обычном редакторе (типа Ноутпада). При записи чисел типизированный файл как правило выигрывает по размеру (не всегда), но если основное содержание текстовое (как тут), то будет скорее наоброт.. Так что я просто рекомендую тебе полностью переключиться на текст (если это разрешается условиями задачи).

если ты со всем этим согласна, читай дальше - описываю, как это сделать.
volvo прав, кое-что придется немного подкорректировать. Во-первых, какой смысл иметь разный формат на вход и выход?? Непременно возникнут противоречия при чтении файлов, созданных одной и той же программой. У тебя же не конвертер, скажем, из jpeg в mp3 (типа шутка smile.gif). Короче,

1. Выбери либо тип vhod_t, либо vyhod_t, а другой тип убери совсем (то есть заменить на выбранный тип). Я думаю, это должен быть vhod_t, так как нет смысла хранить в файле отклонение - его же можно легко посчитать!

Но в типе vhod_t, как уже заметил volvo, поле number описано как byte, чего явно недостаточно при тех номерах, что фигурируют в файле. Вывод:

2. Поле number сделать integer'ом (если и этого недостаточно, то есть бывают номера больше примерно 32000, то LongInt).

Далее, как тоже говорил volvo, в программировании принята американская нотация дейсьвительных чисел, то есть вместо запятой используется точка. Значит нужно:

3. Пройтись по всему файлу данных автозаменой: "," -> ".". Это можно сделать в любом редакторе, типа в Ноутпаде..

Идем дальше. Размещение двух фамилий в одной строке означает, что надо разделять входную информацию на слова. Это некое дополнительное действие, но дело не в том, что нам лень. Дело в том, что такая ситуация может сбить программу с толку, если кому-то вместо просто фамилии захочется ввести имя-отчество или фамилию с именем - тогда пробел между именем и фамилией будет истолкован неверно. Тогда либо нужно запретить ввод в поле фамилии нескольких слов (и следить за этим), либо ввести для разделения фамилий специальный символ и соответствующим образом делить входную строку на две. Я предлагаю поступить по второму методу, и при этом в качестве признака конца фамилии использовать конец строки smile.gif. Это дает явные преимущества: а. файл легче читается; б. для ввода можно использовать процедуру ReadLn. Таким образом:

4. Размести в файле каждую фамилию на отдельной строке.

Теперь касательно самого чтения. Здесь вообще каша.. Зачем ты читаешь сначала в переменную vh_t, а потом перекладываешь в список, да еще по полям?? Мало того, что можно просто переложить в одной строчке так:
NewL^.inf:=vh_t;
- но еще можно и сразу читать в переменную NewL^.inf ! И более того, ты забываешь про существование оператора with, который явно упрощает картину..
Допустим теперь, что ты согласна со мной и читаешь сразу в нужную переменную. Тогда это будет выглядеть так:

5. Оператор
with NewL^.inf do begin
ReadLn(number);
ReadLn(FIOdir);
ReadLn(FIOen);
ReadLn(plan,fact)
end;


При этом, если ты читаешь несколько раз в разных местах (хотя я, убей Бог, не понимаю, зачем), то этот блок операторов можно засунуть в процедуру..
Тут же примерно: зачем ты ресетишь файл вторично и снова проматываешь одну запись?..

6. Убрать строку
reset(file_in); read(file_in,vh_t);

Ну и последнее (пока smile.gif). Поскольку мы теперь считаем файл текстовым, то

7. Заменить описания файлов на:
  file_in:text;
file_out:text;


Увы, это не самое последнее... Дальше нужно заменить оператор записи на аналогичную (как в п.5) последовательность (но с заменой Write на Read, а также вставь пробел между plan и fact:

8. Вот так:
with NewL^.inf do begin
WriteLn(number);
WriteLn(FIOdir);
WriteLn(FIOen);
WriteLn(plan,' ',fact)
end;


Дальше я не понял - зачем ты читаешь файл повторно в процедуре obrabotka_prosmotr? Странно это выглядит.. Короче, это надо либо просто убрать, либо заменить чтение по описанной выше схеме..

Уфф.. Нет, размер явно имеет значение... smile.gif Мне кажется, тебе достаточно для первого раза..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8





Группа: Пользователи
Сообщений: 8
Пол: Женский
Реальное имя: Катерина

Репутация: -  0  +


спасибо, сейчас попробую чё-нить сделать! smile.gif
Вот у меня тоько один вопрос, а как расчитать значения для поля отклонение? ведь файл текстовый.


--------------------
Dear god, make everyone die. Amen.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гуру
*****

Группа: Пользователи
Сообщений: 1 220
Пол: Мужской

Репутация: -  16  +


Цитата(IchLiebeDich @ 2.12.2006 10:43) *

спасибо, сейчас попробую чё-нить сделать! smile.gif
Вот у меня тоько один вопрос, а как расчитать значения для поля отклонение? ведь файл текстовый.

val
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10





Группа: Пользователи
Сообщений: 8
Пол: Женский
Реальное имя: Катерина

Репутация: -  0  +


Цитата(Ozzя @ 2.12.2006 9:31) *

val

blink.gif Эт чё значит?


--------------------
Dear god, make everyone die. Amen.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


Цитата
Вот у меня тоько один вопрос, а как расчитать значения для поля отклонение? ведь файл текстовый.
А что за отклонение? Наверное, также, как и раньше. Ведь в текстовом файле можно хранить не только строки, но и числа.


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12





Группа: Пользователи
Сообщений: 8
Пол: Женский
Реальное имя: Катерина

Репутация: -  0  +


Цитата(Archon @ 3.12.2006 14:38) *

А что за отклонение?

отклонение - имя поля, куда записываются разности значений полей plan и fact.

В текстовом файле хранятся литеры... dry.gif


--------------------
Dear god, make everyone die. Amen.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


Не понимаю, в чём проблема? Считываешь plan и fact и считаешь разность.


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14





Группа: Пользователи
Сообщений: 8
Пол: Женский
Реальное имя: Катерина

Репутация: -  0  +


Цитата(Archon @ 3.12.2006 15:05) *

Не понимаю, в чём проблема? Считываешь plan и fact и считаешь разность.


в том-то и проблема, что оно не считывается...


--------------------
Dear god, make everyone die. Amen.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(IchLiebeDich @ 10.12.2006 13:35) *

в том-то и проблема, что оно не считывается...

Давай-ка поподробнее.. Покажи свой текущий вариант программы, покажи файл данных.. Скажи, какая именно ошибка возникает.
Пойми, что мы не телепаты. smile.gif
O'kay?


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 26.01.2021 19:34
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name