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 байт ) Кол-во скачиваний: 443

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


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


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





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

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


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

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


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


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

Группа: Пользователи
Сообщений: 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 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
IchLiebeDich   работа с файлами   2.12.2006 1:12
IchLiebeDich   Чуствую, ответа мне не дождаться...   2.12.2006 8:17
lapp   Зайди попозже, завтра.. обещаю посмотреть :) немно…   2.12.2006 9:05
volvo   Ты же описываешь входной файл, как file of vhod_t,…   2.12.2006 9:40
IchLiebeDich   а как это сделать? :blink:   2.12.2006 9:53
Ozzя   а как это сделать? :blink: Определить текстовый …   2.12.2006 11:23
lapp   а как это сделать? :blink: Думаю, volvo на этот …   2.12.2006 12:04
IchLiebeDich   спасибо, сейчас попробую чё-нить сделать! :) …   2.12.2006 13:43
Ozzя   спасибо, сейчас попробую чё-нить сделать! :) …   2.12.2006 14:31
IchLiebeDich   val :blink: Эт чё значит?   3.12.2006 19:02
Archon   А что за отклонение? Наверное, также, как и раньше…   3.12.2006 19:38
IchLiebeDich   А что за отклонение? отклонение - имя поля, куда…   3.12.2006 19:55
Archon   Не понимаю, в чём проблема? Считываешь plan и fact…   3.12.2006 20:05
IchLiebeDich   Не понимаю, в чём проблема? Считываешь plan и fac…   10.12.2006 16:35
Lapp   в том-то и проблема, что оно не считывается... Д…   11.12.2006 15:10


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

 





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