Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.04.2014, 12:41   #1
Thabian
Пользователь
 
Регистрация: 02.04.2014
Сообщений: 12
По умолчанию замена данных в базе, типизированный файл

Есть база в типизированном файле.
Выполняю замену данных в одной из строк.. вроде код написан, но в базе изменений не происходит, выводит изначальный вариант.
Код:
program zamena;
uses crt;
const n=10;
type zap=record 
	prodavec:string[8];
	marka:string[15];
	god, oborot:integer;
	date:string[8]
	end;
var d: file of zap;
    z: zap;
    mas:array[1..n] of zap;
    i,e: integer;
    t,r: string;
    
begin
    clrscr;
    assign (d, 'E:\d.txt');
    reset(d);
    write('Vvedite marky: '); readln (t);
    write('Vvedite new marky: '); readln(r);
    write('Vvedite new god: '); readln(e);
    clrscr;
    i:=1;
    while not eof (d) do begin
        read (d, z);
        mas[i]:=z; 
        i:=i+1;
        end;
    while not eof (d) do begin
        read (d, z);
        if t=mas[i].marka then begin
        mas[i].marka:=r;
        mas[i].god:=e;
        end;
    write (d,z);
    end;
    close (d);
    reset (d);
writeln('----------------------------------------------------------');
writeln('| Prodavec |     Marka     |  God  | Oborot  |  Data  |');
writeln('----------------------------------------------------------');
reset (d);
for i:=1 to n do 
   with mas[i] do begin
    gotoXY(1,whereY);write('| ',prodavec);
    gotoXY(12,whereY);write('| ',marka);
    gotoXY(28,whereY);write('| ',god);
    gotoXY(36,whereY);write('| ',oborot);
    gotoXY(47,whereY);write('| ',date);
    gotoXY(58,whereY);writeln('| ');
   end;
writeln('----------------------------------------------------------');
end.


___________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE]
(кнопочка на панели форматирования с решёточкой #)
Не забывайте об этом!

Модератор.

Последний раз редактировалось Serge_Bliznykov; 02.04.2014 в 13:05.
Thabian вне форума Ответить с цитированием
Старый 02.04.2014, 13:08   #2
ZX Spectrum-128
Участник клуба
 
Регистрация: 05.11.2013
Сообщений: 1,601
По умолчанию

Вы изменения делаете для элемента массива, а не для записи.
И пишете в файл исходную запись.


Если вам нужно редактировать конкретную запись в файле, необязательно читать весь файл. И не нужно читать его в массив.
Код:
Seek(f, nz); // nz - номер записи, нумерация с нуля
Read(f,z);
// изменили запись
Write(f,z);
....

Последний раз редактировалось ZX Spectrum-128; 02.04.2014 в 13:11.
ZX Spectrum-128 вне форума Ответить с цитированием
Старый 02.04.2014, 13:11   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

ну, как минимум, перед поиском записей стоит установить указатель на начало файла. Это можно сделать процедурой Reset(f) или Seek(f,0):
Код:

  while not eof (d) do begin
        read (d, z);
        mas[i]:=z; 
        i:=i+1;
        end;

   seek(f, 0);

    while not eof (d) do begin
....
во-вторыХ, как правильно сказал ZX Spectrum-128, раз Вы в массиве изменяете, так и писать нужно элемент массива, а не исходную запись!
Код:
write (d, mas[i]);
И ещё исправьте ошибку - совершенно не обязательно, что в файле ровно N записей. Нужно считать, сколько записей Вы прочитали в массив (а в данном случае можно вообще без массива обойтись!)

p.s. ну и учтите, что чтение в массив можно упростить...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 02.04.2014, 13:25   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

увидел, что в программе присутствует ещё несколько косячков..
позволил себе переписать код без массива...

Код:
program zamena;
uses crt;
type zap = record
    prodavec: string[8];
    marka: string[15];
    god, oborot: integer;
    date: string[8]
  end;
var d: file of zap;
  z: zap;
  i, k, newGod : integer;
  t, newMarka: string;

begin
  clrscr;
  write('Vvedite marky: '); readln(t);
  write('Vvedite new marky: '); readln(newMarka);
  write('Vvedite new god: '); readln(newGod);
  clrscr;
  assign(d, 'd:\d.txt');
  reset(d);
  i := 0;
  k := 0; {количество замен}
  while not eof(d) do begin
    read(d, z);
    if z.marka = t then begin
      z.marka := newMarka;
      z.god := newGod;
      seek(d, i);
      write(d, z);
      inc(k);
    end;
    i := i + 1;
  end;
  close(d);
  WriteLn('Done. Changed ',k,' records OldMarka -> NewMarka');
  WriteLn('Press ENTER to continue...');
  ReadLn;

  reset(d);
  writeln('----------------------------------------------------------');
  writeln('| Prodavec |     Marka     |  God  | Oborot  |  Data  |');
  writeln('----------------------------------------------------------');
  reset(d);
  while not eof(d) do begin
    read(d, z);
    with z do begin
      gotoXY(1, whereY); write('| ', prodavec);
      gotoXY(12, whereY); write('| ', marka);
      gotoXY(28, whereY); write('| ', god);
      gotoXY(36, whereY); write('| ', oborot);
      gotoXY(47, whereY); write('| ', date);
      gotoXY(58, whereY); writeln('| ');
    end;
    writeln('----------------------------------------------------------');
  end;
  Close(d);
  readln
end.

p.s. если нужно с массивом, скажите, перепишу ваш код с использованием массива...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 02.04.2014, 13:48   #5
Thabian
Пользователь
 
Регистрация: 02.04.2014
Сообщений: 12
По умолчанию

Спасибо. Здесь действительно можно без массива.

Есть еще такой вопрос. По этой же базе данных нужно подсчитать оборот по каждому продавцу. Продавцы в базе повторяются и оборот считается столько раз, сколько встречается фамилия, то есть по каждой строке.
Как поставить условие, чтобы итоговый оборот по каждой фамилии был посчитан только один раз?

Код:
program oborot;
uses crt;
const n=10;
type zap=record 
	prodavec:string[8];
	marka:string[15];
	god, oborot:integer;
	date:string[8]
	end;
type prod = set of 1..n;
var d: file of zap;
    z: zap;
    mas:array[1..10] of zap;
    i, j: integer;
    a:longint;
    pr:set of byte;
       
begin
clrscr;
assign (d, 'E:\d.txt');
reset(d);
i:=1;
while not eof (d) do
    begin
        read(d,z);
        mas[i]:=z; 
        i:=i+1;
        end;
pr:=[];
for i:=1 to n do begin
    a:=mas[i].oborot;
    for j:=i+1 to n do 
    if mas[i].prodavec = mas[j].prodavec then begin
        a:=a+mas[j].oborot; 
        pr:=pr+[i];
        end;
    if i in pr then writeln (mas[i].prodavec, ' ', a);
a:=0;
 end;
end.
Thabian вне форума Ответить с цитированием
Старый 02.04.2014, 14:08   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

считайте данные в массив, отсортируйте массив по продавцу (это обеспечит, что одинаковые продавцы будут идти в массиве ПОДРЯД).
Потом просто:
берём первого продавца (max[1].prodavec и идём по массиву, пока mas[i] равно взятому продавцу, всё встреченные обороты суммируем.
Как только продавец сменился - выдаём результат по запомненному продавцу, запоминаем нового, сбрасываем обороты (начинаем считать заново, с mas[i].oborot
и так до конца массива.
всё!

p.s. Вы так и не исправили грубую ошибку чтения записей из файла в массив.
Записей в файле может быть совсем не 10, поэтому нужно подсчитывать фактическое N, сколько записей реально прочитали в массив!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 02.04.2014, 14:35   #7
Thabian
Пользователь
 
Регистрация: 02.04.2014
Сообщений: 12
По умолчанию

Да, массив понятно что mas:array[1..n] of zap;

Добавил сортировку по алфавиту, изменил условие вывода данных, теперь выдает ошибку "индекс вне границ массива"

Код:
begin
clrscr;
assign (d, 'E:\d.txt');
reset(d);
i:=1;
while not eof (d) do
    begin
        read(d,z);
        mas[i]:=z; 
        i:=i+1;
        end;
for i:=1 to n do
for j:=1 to n do 
    if mas[i].prodavec < mas[j].prodavec then begin
         z:=mas[i];
         mas[i]:=mas[j];
         mas[j]:=z; 
         end;
for i:=1 to n do begin
    a:=mas[i].oborot;
    for j:=i+1 to n do 
    if mas[i].prodavec = mas[j].prodavec then begin
        a:=a+mas[j].oborot; 
        end;
    if mas[i].prodavec <> mas[j].prodavec then writeln (mas[i].prodavec, ' ', a);
a:=0;
 end;
end.
Thabian вне форума Ответить с цитированием
Старый 02.04.2014, 14:47   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

не так.
а вот так:
Код:
begin
clrscr;
assign (d, 'E:\d.txt');
reset(d);
i:=0;
while not eof (d) do
    begin
        i:=i+1; {тут можно добавить проверку, если i больше n - то записи в массив не помещаются, 
          нужно выдавать сообщение пользователю, прерывать цикл и выходить... }
        read(d, mas[i]);
    end;
NN := i; {запомнили, сколько у нас записей в массиве!}

if NN<1 then {массив пуст, прерываем программу} Halt(1);

{сортировка массива по продавцу}
for i:=1 to NN-1 do
for j:=i+1 to NN do 
    if mas[i].prodavec < mas[j].prodavec then begin
         z:=mas[i];
         mas[i]:=mas[j];
         mas[j]:=z; 
   end;


t:=mas[1].prodavec;
a:= mas[1].oborot;
for i:=2 to NN do begin
    if mas[i].prodavec = t then a := a + mas[i].oborot
    else begin
       WriteLn('Prodavec: ', t, '  oborot = ', a);
       t := mas[i].prodavec;
       a := mas[i].oborot;
    end;
end;
{выведем последнего продавца}
WriteLn('Prodavec: ', t, '  oborot = ', a);
end.

Последний раз редактировалось Serge_Bliznykov; 02.04.2014 в 15:48.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 02.04.2014, 15:37   #9
Thabian
Пользователь
 
Регистрация: 02.04.2014
Сообщений: 12
По умолчанию

Отлично! С маленькой поправкой все работает как надо.

Там только где t:=mas[1].prodavec; a:= mas[i].oborot;
надо оборот тоже писать 1 вместо i.

Благодарю
Thabian вне форума Ответить с цитированием
Старый 02.04.2014, 15:48   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Thabian Посмотреть сообщение
Отлично! С маленькой поправкой все работает как надо.

Там только где t:=mas[1].prodavec; a:= mas[i].oborot;
надо оборот тоже писать 1 вместо i.
Ага. Вы правы! Я накосячил. Сейчас поправлю у себя в сообщении.

Всегда пожалуйста!!
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Имеется типизированный файл с тридцатью числами. Записать в другой файл числа имеющегося файла в обратном порядке. Валентин77 Общие вопросы C/C++ 8 17.12.2013 22:53
Тип данных запись, необходимо создать типизированный файл записей sifa Помощь студентам 1 29.11.2011 21:56
Типизированный файл с натуральными числами. Числа, встречающиеся 1 раз переписать в другой файл [Паскаль] mifomen Помощь студентам 7 16.12.2010 22:00