Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/35: Рейтинг темы: голосов - 35, средняя оценка - 4.69
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
1

Запись в типизированный файл по строкам

17.04.2012, 17:21. Показов 6586. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
уважаемые знатоки и просто такие же как я нубы, зашедшие сюда =)
начал изучать типизированные файлы. не могу понять как выполнить запись в типизированный фал ПО СТРОКАМ
задача такова - дан файл веществ чисел, содержащий элементы прямолуг матрицы по строкам, причем первый элемент - количество столбцов. получить новый файл такой же структуры с транспонированной матрицей
получить новый файл, с транспонированной матрицей.
я так понимаю что файл внутри машины можно представляется как то так
m
1 2 3 4 5
6 7 8 9 0
1 4 6 5 7
где m кол-во столбов..
в общем не могу представить, как это реализовать.
очень прошу - НЕ кидать готовое решение. очень хочу это понять сам и разобраться.

пока мысли такие - как то записывать в файл каждую строку и добавлять в конец каждой элементы с кодами #13#10
а при считывании в программу, добавить ее в некую матрицу, потом из которой перезалить в новый файл.
Динамические массивы не использовали и не проходили - следовательно ими пользоваться нельзя.

в общем помогите разобраться...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.04.2012, 17:21
Ответы с готовыми решениями:

Запись в типизированный файл
Создать типизированный файл и записать в него 5 одинаковых вещественных чисел, 5 одинаковых слов, 5...

Запись в типизированный файл
Помогите пожалуйста разобраться с ошибкой type sports_data = class FIO_C:string; ...

Запись в типизированный файл
Тут такое дело, при записи в типизированный файл всё нормально , но при последующий записи...

Запись в типизированный файл
Помогите пожалуйста, как записать инфо из 4 полей edit, которые содержат ФИО и возраст в...

18
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
17.04.2012, 17:41 2
У Вас файл ТИПИЗИРОВАННЫЙ, а не текстовый! Зачем #10?..
Как в программе хранится сам массив? Array of Array? Если вы указываете Type A = Array of Double; То записать переменную этого типа в файл функцией Write не получится, поскольку не известна длинна массива. Писать в файл можно только в случае если Type A = Array[0..100] of Double; А если длинна массива не известна, то сначала в файл записывать размерность (n,m:Integer), а потом в цикле заносить элементы используя SizeOf(Тип), читать также, сдвигаясь на нужное число байт.
Еще про типизированные файлы можно почитать тут: http://delphi-faq.zoxt.net/b74.htm
1
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 17:44 3
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Зная количество элементов в столбце можно прочитать данные из файла и правильно записать их в двумерный массив.

Этот код ниже, я сейчас подправлю...
...
Исправлено (но не проверено в работе):
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
procedure TForm1.Button1Click(Sender: TObject);
const
  Fn = 'file.dat';
  //Величина приращения длины динамического массива по строкам.
  Capacity = 10;
var
  F : file of Extended;
  Arr : array of array of Extended;
  Num : Extended;
  i, j, M : Integer;
  FileName : String;
begin
  FileName := ExtractFilePath(ParamStr(0)) + Fn;
  if not FileExists(FileName) then begin
    ShowMessage('Файл с данными не найден. Действие отменено.');
    Exit;
  end;
 
  AssignFile(F, FileName);
  Reset(F);
  //Читем и анализируем сведения о количестве столбцов.
  Num := 0;
  if not Eof(F) then Read(F, Num);
  M := Trunc(Num);
  if M <= 0 then begin
    ShowMessage('Неверный формат файла. Действие отменено.');
    CloseFile(F);
    Exit;
  end;
 
  //Теперь читаем из файла следующие элементы и записываем их построчно в массив.
  i := 0;
  while not Eof(F) do begin
    //Если требуется, увеличиваем размер динамического массива.
    if i = Length(Arr) then SetLength(Arr, i + Capacity, M);
    //Читаем данные очередной строки.
    j := 0;
    while not Eof(F) do begin
      Read(F, Arr[i, j]);
      //Количество прочитанных элементов строки (столбцов).
      Inc(j);
      //Если прочитали М элементов - значит надо перейти к следующей строке.
      if j = M then Break;
    end;
    //Количество прочитанных строк.
    Inc(i);
  end;
  CloseFile(F);
  //Корректируем размер массива.
  if i < Length(Arr) then SetLength(Arr, i);
 
  //Теперь в массив Arr записаны элементы из файла F.
  //Сейчас в переменной i записано количество прочитанных строк,
  //а в переменной j - количество прочитанных элементов в последней строке массива.
  //...
end;
Здесь я зря реализовал последовательные приращения длины массива. Надо было по-другому сделать - размеры можно определить в самом начале по количеству элементов в файле FileSize(F) и по известному количеству столбцов.
1
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 17:51  [ТС] 4
в программе он не хранится.
нам дается типизированный файл, в котором находятся элементы массива
Еще про типизированные файлы можно почитать тут: http://delphi-faq.zoxt.net/b74.htm
была открыта эта вкладка =) читал, но мало что дало

Добавлено через 5 минут
Mawrat,
Delphi
1
Arr : array[1..N, 1..M] of Extended;
это же получается - динамический массив.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 18:03 5
Так я же там написал - что этот код я буду ещё править.
---
Я подправил код. Но в работе его пока не проверял.
0
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 18:11  [ТС] 6
ну вообще чужие мысли немного прояснили мне алгоритм.
думаю делать так - сначала пользователь вводит кол-во элементов, потом они рандомно задаются,
массив сделаю статический, 100 на 100, потому что мы не проходили динамические - а нам и скажут тогда делать без них.
потом определяю длинну файла - т.е. кол-во элементов.
считываю первый элемент и колво-во всех элементов делю на коло столбцов - тем самым я определю, массив каких размеров мне нужно создать.
ну а дальше как получится =)

Добавлено через 43 секунды
Mawrat,
спасибо конечно, но
Цитата Сообщение от CaH_CaHbl4 Посмотреть сообщение
Динамические массивы не использовали и не проходили - следовательно ими пользоваться нельзя.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 18:25 7
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Можно и со статическим сделать. Сейчас напишу...
Со статическим массивом:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
procedure TForm1.Button1Click(Sender: TObject);
const
  Fn = 'file.dat';
  N = 100;
  M = 20;
var
  F : file of Extended;
  Arr : array[1..N, 1..M] of Extended;
  Num : Extended;
  i, j, Mf : Integer;
  FileName : String;
begin
  FileName := ExtractFilePath(ParamStr(0)) + Fn;
  if not FileExists(FileName) then begin
    ShowMessage('Файл с данными не найден. Действие отменено.');
    Exit;
  end;
 
  AssignFile(F, FileName);
  Reset(F);
  //Читем и анализируем сведения о количестве столбцов.
  Num := 0;
  if not Eof(F) then Read(F, Num);
  Mf := Trunc(Num);
  if Mf <= 0 then begin
    ShowMessage('Неверный формат файла. Действие отменено.');
    CloseFile(F);
    Exit;
  end;
  if Mf > M then begin
    ShowMessage('Количество столбцов в массиве меньше, чем в файле. Данные будут усечены.');
    Mf := M;
  end;
 
  //Теперь читаем из файла следующие элементы и записываем их построчно в массив.
  i := 0;
  while not Eof(F) do begin
    //Количество прочитанных строк.
    Inc(i);
    //Читаем данные очередной строки.
    j := 0;
    while not Eof(F) do begin
      //Количество прочитанных элементов строки (столбцов).
      Inc(j);
      Read(F, Arr[i, j]);
      //Если прочитали Мf элементов - значит надо перейти к следующей строке.
      if j = Mf then Break;
    end;
    //Если это последняя строка массива, то прерываем чтение из файла.
    if i = N then Break;
  end;
  CloseFile(F);
 
  //Теперь в массив Arr записаны элементы из файла F.
  //Сейчас в переменной i записано количество прочитанных строк,
  //а в переменной j - количество прочитанных элементов в строке i.
  //...
end;
1
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 18:26  [ТС] 8
и работаем мы только в консольном режиме(((
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 18:29 9
Сейчас в консоли сделаем...
1
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 18:33  [ТС] 10
вы уж извините - задолбал уже наверное =)
у меня вот что получилось
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils,windows;
const
  nmax = 100;
  mmax = 100;
type
  tfile = file of Real;
var
  f,g:tfile;
  f_mas:array[1..nmax,1..mmax] of Real;
  i,j,n,m,kol:integer;
  q:real;
begin
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  AssignFile(f,'data.dat');
  Rewrite(f);
  Writeln('Сколько чисел хотите записать в файл? (первый элемент - есть колво столбцов матрицы');
  Readln(kol);
  for i:=0 to kol-1 do
    begin
      Read(q);
      write(f,q);
    end;
  CloseFile(f);
 
  Reset(f);
  read(f,q);
  CloseFile(f);
  m:=Trunc(q);
  if (kol mod m)=0 then n:=Round(kol/m)
  else n:=Round(kol/m)+1;
 
 
  Reset(f);
  for i:=0 to kol-1 do
    begin
      Read(f,q);
      Writeln(q);
    end;
 
 
  CloseFile(f);
  Writeln('n=',n);
  Writeln('m=',m);
  Readln;
  Readln;
end.
программа пока что просто определяет размеры массива в которй смогут поместиться все данные из файла
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 18:51 11
CaH_CaHbl4, а нужно запись сделать? А я чтение пишу... Но чтение всё равно понадобится.
---
В консоли. Чтение из файла и запись в массив:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils, Windows;
 
const
  Fn = 'file.dat';
  N = 100;
  M = 20;
var
  F : file of Extended;
  Arr : array[1..N, 1..M] of Extended;
  Num : Extended;
  i, j, Mf : Integer;
  S, FileName : String;
begin
  //Переключение окна консоли на кодовую страницу CP1251 (Win-1251).
  //Если после переключения русские буквы показываются неверно,
  //следует открыть системное меню консольного окна - щелчком мыши в левом
  //верхнем углу окна консоли и выбрать:
  //Свойства - закладка "Шрифт" - выбрать шрифт: "Lucida Console".
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
 
  FileName := ExtractFilePath(ParamStr(0)) + Fn;
  AssignFile(F, FileName);
  repeat
    Writeln('Файл данных: ', FileName);
    if not FileExists(FileName) then begin
      Writeln('Файл с данными не найден. Действие отменено.');
      Writeln('Повторить - Enter. Выход - любой символ + Enter.');
      Readln(S);
      Continue;
    end;
 
    Reset(F);
    //Читем и анализируем сведения о количестве столбцов.
    Num := 0;
    if not Eof(F) then Read(F, Num);
    Mf := Trunc(Num);
    if Mf <= 0 then begin
      Writeln('Неверный формат файла. Действие отменено.');
      CloseFile(F);
      Writeln('Повторить - Enter. Выход - любой символ + Enter.');
      Readln(S);
      Continue;
    end;
    if Mf > M then begin
      Writeln('Количество столбцов в массиве меньше, чем в файле. Данные будут усечены.');
      Mf := M;
    end;
 
    //Теперь читаем из файла следующие элементы и записываем их построчно в массив.
    i := 0;
    while not Eof(F) do begin
      //Количество прочитанных строк.
      Inc(i);
      //Читаем данные очередной строки.
      j := 0;
      while not Eof(F) do begin
        //Количество прочитанных элементов строки (столбцов).
        Inc(j);
        Read(F, Arr[i, j]);
        //Если прочитали Мf элементов - значит надо перейти к следующей строке.
        if j = Mf then Break;
      end;
      //Если это последняя строка массива, то прерываем чтение из файла.
      if i = N then Break;
    end;
    CloseFile(F);
 
    //Теперь в массив Arr записаны элементы из файла F.
    //Сейчас в переменной i записано количество прочитанных строк,
    //а в переменной j - количество прочитанных элементов в строке i.
    //...
 
    Writeln('Повторить - Enter. Выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
Здесь можно сделать немного по-другому - заранее определиться в соотношении между размером массива и количеством элементов в файле. - По количеству элементов в файле FileSize(F) и по известному количеству столбцов.
Зато в нынешнем виде сам алгоритм пригоден для чтения неизвестного количества данных. - Например, на случай, если бы у нас был не типизированный, а текстовый файл.

Добавлено через 4 минуты
Сейчас вот смотрю - усечение я неверно сделал. При усечении надо перепрыгивать на следующую строку, а у меня идёт чтение дальше в строке. В результате этого, если в файле строки шире, чем в массиве, то данные будут читаться в неверном порядке...
---
Т. е., сейчас этот алгоритм пригоден только для случая, когда ширина таблицы в файле не превышает ширины (количества столбцов) в массиве.
1
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 18:53  [ТС] 12
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils,windows;
const
  nmax = 100;
  mmax = 100;
type
  tfile = file of Real;
var
  f,g:tfile;
  f_mas:array[0..nmax,0..mmax] of Real;
  i,j,n,m,kol:integer;
  q:real;
begin
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  AssignFile(f,'data.dat');
  Rewrite(f);
  Writeln('Сколько чисел хотите записать в файл? (первый элемент - есть колво столбцов матрицы');
  Readln(kol);
  {записываем числа в файл}
  for i:=0 to kol-1 do
    begin
      Read(q);
      write(f,q);
    end;
  CloseFile(f);
 
  Reset(f);
  read(f,q); {считываем первый эдемент. тип нужно преобразовать, т.к. в данный момент тип реал
  защиту от дурака напишу позже}
  CloseFile(f);
  m:=Trunc(q); {преобразовываем тип и получам, чтколько у нас ттолбиков}
  {узнаем, сколько нужно взять строк, чтобы пометились все элементы их файла}
  if (kol mod m)=0 then n:=Round(kol/m)
  else n:=Round(kol/m)+1;
 
 
  {инициализируем массив}
  for i:=0 to n-1 do
  for j:=0 to m-1 do
  f_mas[i,j]:=0;
 
  {теперь построчно записываем из файла в наш массив}
  Reset(f);
  i:=0;
  while not eof(f) and (i<n) do
  begin
    j:=0;
    while (not eof(f)) and (j<m) do
      begin
        read(f,f_mas[i,j]);
        inc(j);
      end;
    inc(i);
   end;
  for i:=0 to n-1 do
  begin
    for j:=0 to m-1 do write(f_mas[i,j]:6:0);
    Writeln;
  end;
 
  CloseFile(f);
 
  Readln;
  Readln;
end.
когда читаем элементы, нужно же еще контролировать границы, ведь у Вас за циклом смотрит только eof, а нужно контролировать и кол-во чисел в строке
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 18:58 13
Вариант с исправлениями:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils, Windows;
 
const
  Fn = 'file.dat';
  N = 100;
  M = 20;
var
  F : file of Extended;
  Arr : array[1..N, 1..M] of Extended;
  Num : Extended;
  i, j, Mf : Integer;
  S, FileName : String;
begin
  //Переключение окна консоли на кодовую страницу CP1251 (Win-1251).
  //Если после переключения русские буквы показываются неверно,
  //следует открыть системное меню консольного окна - щелчком мыши в левом
  //верхнем углу окна консоли и выбрать:
  //Свойства - закладка "Шрифт" - выбрать шрифт: "Lucida Console".
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
 
  FileName := ExtractFilePath(ParamStr(0)) + Fn;
  AssignFile(F, FileName);
  repeat
    Writeln('Файл данных: ', FileName);
    if not FileExists(FileName) then begin
      Writeln('Файл с данными не найден. Действие отменено.');
      Writeln('Повторить - Enter. Выход - любой символ + Enter.');
      Readln(S);
      Continue;
    end;
 
    Reset(F);
    //Читем и анализируем сведения о количестве столбцов.
    Num := 0;
    if not Eof(F) then Read(F, Num);
    Mf := Trunc(Num);
    if (Mf <= 0) or (Mf > M) then begin
      Writeln('Неверный формат файла. Действие отменено.');
      CloseFile(F);
      Writeln('Повторить - Enter. Выход - любой символ + Enter.');
      Readln(S);
      Continue;
    end;
 
    //Теперь читаем из файла следующие элементы и записываем их построчно в массив.
    i := 0;
    while not Eof(F) do begin
      //Количество прочитанных строк.
      Inc(i);
      //Читаем данные очередной строки.
      j := 0;
      while not Eof(F) do begin
        //Количество прочитанных элементов строки (столбцов).
        Inc(j);
        Read(F, Arr[i, j]);
        //Если прочитали Мf элементов - значит надо перейти к следующей строке.
        if j = Mf then Break;
      end;
      //Если это последняя строка массива, то прерываем чтение из файла.
      if i = N then Break;
    end;
    CloseFile(F);
 
    //Теперь в массив Arr записаны элементы из файла F.
    //Сейчас в переменной i записано количество прочитанных строк,
    //а в переменной j - количество прочитанных элементов в строке i.
    //...
 
    Writeln('Повторить - Enter. Выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
Добавлено через 3 минуты
Цитата Сообщение от CaH_CaHbl4 Посмотреть сообщение
когда читаем элементы, нужно же еще контролировать границы, ведь у Вас за циклом смотрит только eof, а нужно контролировать и кол-во чисел в строке
Нет - количество элементов и в столбцах и строках проверяется. И выхода за границы там не будет. Защита от нарушения границ по столбцам: 63 строка в коде. Защита от нарушения границ по строкам: 66 строка.
1
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 18:59  [ТС] 14
53 и 58 строка в Вашем последнем варианте.
ведь не будет же работать коректно, у Вас он из этого цикла выйдет только тогда, когда будет достигнут конец файла.
или же все будет вылетать с весельем, так как получится выход за границы массива.
или я что-то не понимаю?

добавил
извините, не заметил что у вас там через условный оператор стоит break
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 19:02 15
53 и 58 - это проверки на конец файла. Плюс к этому, 63 и 66 строки - проверки границ массива. Т. е., учтён и размер файла и размер массива - как положено, собственно.
0
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 19:05  [ТС] 16
ну вот впринципе и начинаю немного разбираться в ситуации.
только вот смотря на ваш код - откуда вы определили колво строк?
у меня за это отвечает
if (kol mod m)=0 then n:=Round((kol)/m)
else n:=Round((kol+1)/m);
где kol это кол-во элементов в файле, а m это первый элемент файла, т.е. показывает кол-во столбиков
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
17.04.2012, 19:11 17
У меня в коде заранее количество строк не определяется. Количество строк уточняется по мере чтения из файла. Прочитали очередную строку - увеличили счётчик строк: Inc(i). И так до момента, когда достигнем конца файла или когда будет достигнута последняя строка в массиве.
Здесь можно по-разному действовать - можно так как у тебя - сразу количество строк определить.
1
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
17.04.2012, 21:33  [ТС] 18
ну в общем то и спасибо на этом =)
теперь осталось то дело за малым, завести сначала цикл по столбцам, потом по строкам и записат ьв новый файл с транспонированной матрицей

Добавлено через 2 часа 13 минут
в итоге вот что у меня получилось
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils,
  windows;
 
const
  nmax = 100;
  mmax = 100;
type
  tfile = file of Real;
var
  f,g:tfile;
  f_mas:array[1..nmax,1..mmax] of Real;
  g_mas:array[1..mmax,1..nmax] of Real;
  i,j,n,m,kol:integer;
  q:real;
begin
  Randomize;
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  AssignFile(f,'matrix.dat');
  AssignFile(g,'matrix_trans.dat');
 
  {запишем числа в файл}
  Rewrite(f);
  Writeln('Сколько чисел хотите записать в файл?');
  repeat
    Readln(kol);
    if kol>nmax*mmax
    then
      begin
        Writeln('На столько чисел программа не расчитана. Максимум ',nmax*mmax,' элементов');
        writeln('Повторите ввод');
      end;
  until kol<=nmax*mmax;
  Writeln('Введите нулевой элемент - это кол-во столбцов матрицы');
  Readln(q);
  write(f,q);
  Writeln('Остальные элементы зададутся рандомно');
  for i:=1 to kol do
      begin
      q:=Random(15)-6;
      write(q:3:2); write(' ');
      write(f,q);
      end;
  CloseFile(f);
 
  {прочтем первый элемент. нам нужно узнать, сколько столбцов}
  Reset(f);
  read(f,q);
  CloseFile(f);
  Writeln;
  {кол-во столбцов сейчас в переменной q. она у нас типа real}
  m:=Trunc(q); {преобразуем тип}
  if (m<=0) or (m>mmax)
  then
    begin
      Writeln('Неправильный файл. Программа завершает работу');
      Exit;
    end;
 
  {теперь посчитаем,
  во сколько строк влезут все данные}
  if (kol mod m)=0
  then n:=Round((kol)/m)
  else n:=Round((kol+1)/m);
  Writeln;
 
  {выведем содержимое файла с исходной матрицу}
  Reset(f);
  Writeln('Содержимое файла с исходной матрицей:');
  while not Eof(f) do
    begin
      read(f,q);
      Writeln(q:6:2);
    end;
  CloseFile(f);
 
  {инициализируем массив, в который мы будем вставлять числа из файла}
  for i:=0 to n-1 do
  for j:=0 to m-1 do
  f_mas[i,j]:=0;
 
  {теперь построчно записываем из файла в наш массив}
  Reset(f);
  Seek(f,1); {указатель в положение 1, т.к. в 0 месте у нас находится кол-во столбцов}
  i:=1;
  while not eof(f) and (i<=n) do
  begin
    j:=1;
    while (not eof(f)) and (j<=m) do
      begin
        {читаем и записываем в массив}
        read(f,f_mas[i,j]);
        inc(j);
      end;
    inc(i);
   end;
 
  {выведем наш массив}
  Writeln('Сформированный массив из исходного файла:');
  for i:=1 to n do
  begin
    for j:=1 to m do write(f_mas[i,j]:6:2);
    Writeln;
  end;
  CloseFile(f);
 
  q:=n/1;
  Rewrite(g);
  write(g,q); {на первое место пишем кол-во столбцов транспонированной матрицы
  это число строк исходной матрицы}
  {сначала бежим по строкам, а потом уже по столбцам
  в итоге в файл запишется мастрица транспонированная}
  for j:=1 to m do
    for i:=1 to n do write(g,f_mas[i,j]);
  CloseFile(g);
 
  {выведем содержимое выходного файла}
  Writeln('Файл с транспонированной матрицей:');
  Reset(g);
  while not eof(g) do
    begin
      read(g,q);
      Writeln(q:6:2);
    end;
  CloseFile(g);
  {сформируем из этого файла матрицу
  если все норм, тогда матрица должна быть транспонирована относительно исходной}
  Writeln('Матрица из выходного файла:');
  Reset(g);
  Seek(g,1);
  i:=1;
  while not eof(g) and (i<=m) do
  begin
    j:=1;
    while (not eof(g)) and (j<=n) do
      begin
        read(g,g_mas[i,j]);
        inc(j);
      end;
    inc(i);
   end;
  for i:=1 to m do
    begin
      for j:=1 to n do
        begin
          write(g_mas[i,j]:6:2);
          write(' ');
        end;
      writeln;
    end;  
  Readln;
  Readln;
end.
0
22 / 22 / 8
Регистрация: 12.02.2012
Сообщений: 137
19.04.2012, 21:35  [ТС] 19
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

перепелил задачу полностью =)
когда написал код, пришла идея не использовать матрицы вообще. ибо много памяти чтобы не расходовать.
понимаю - сейчас памяти много у всех. но если уж кодить, то кодить грамотно
если вдруг интересно как =)
суть такова, что нужно взять элемент i из f и поместить в g потом взять элемент i+m из f и поместить в g и т.д.
т.е. мы как бы бегаем по столбцам матрицы из файла f и поэлементно пишем их в файл g
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils,
  windows;
 
type
  tfile = file of Real;
var
  f,g:tfile;
  i,j,n,m,kol:integer;
  q:real;
 
procedure print_matrix(var f:tfile);
var
  n_loc,m_loc,i,j:Integer;
  q:Real;
begin
  Reset(f);
  read(f,q);
  {кол-во столбцов сейчас в переменной q. она у нас типа real}
  m_loc:=Trunc(q); {преобразуем тип}
  n_loc:=1;
  {теперь посчитаем,
  во сколько строк влезут все данные}
  repeat
    n_loc:=n_loc+1;
  until m_loc*n_loc>=kol;
  Seek(f,1); {указатель в положение 1, т.к. в 0 месте у нас находится кол-во столбцов}
  i:=1;
  while not eof(f) and (i<=n_loc) do
  begin
    j:=1;
    while (not eof(f)) and (j<=m_loc) do
      begin
        read(f,q);
        write(q:5:1);
        Inc(j);
      end;
    Writeln;
    inc(i);
   end;
 
end;
begin
  Randomize;
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  AssignFile(f,'files\matrix.dat');
  AssignFile(g,'files\matrix_trans.dat');
 
  {запишем числа в файл}
  Rewrite(f);
  Writeln('Сколько чисел хотите записать в файл?');
  Readln(kol);
 
  Writeln('Введите нулевой элемент - это кол-во столбцов матрицы');
  Readln(q);
  write(f,q);
  Writeln('Остальные элементы зададутся рандомно');
  for i:=1 to kol do
    begin
      q:=Random(15)-6;
      write(q:3:2); write(' ');
      write(f,q);
    end;
  CloseFile(f);
 
  {прочтем первый элемент. нам нужно узнать, сколько столбцов}
  Reset(f);
  read(f,q);
  CloseFile(f);
  Writeln;
 
  {кол-во столбцов сейчас в переменной q. она у нас типа real}
  m:=Trunc(q); {преобразуем тип}
  if (m<=0)
  then
    begin
      Writeln('Неправильный файл. Программа завершает работу');
      Exit;
    end;
 
   n:=1;
  {теперь посчитаем,
  во сколько строк влезут все данные}
  n:=1;
  repeat
    n:=n+1;
  until m*n>=kol;
  Writeln ('Кол-во столбцов ',m);
  Writeln('Достаточно ',n,' строк(и)');
  Writeln;
 
  Reset(f);
  Writeln('Содержимое файла с исходной матрицей:');
  while not Eof(f) do
    begin
      read(f,q);
      Write(q:5:1);
      write(' ');
    end;
  CloseFile(f);
 
  {Допределим наш файл, чтобы можно было корректно создать из него матрицу
  для этого нужно дописать в конец столько элементов, чтобы их количество было равно n*m}
  if n*m<>kol
  then
    begin
      reset(f);
      Seek(f,kol+1);
      repeat
        q:=0;
        write(f,q);
        Inc(kol);
      until n*m=kol;
      CloseFile(f);
    end;
 
  Reset(f);
  Rewrite(g);
  q:=n/1;
  write(g,q); //записали колво столбиков транспонированной матрицы - это есть кол-во строк исходной
 
  for j:=1 to m do
    begin
      i:=j;
      while not Eof(f) and (i<=kol) do
        begin
          Seek(f,i);
          read(f,q);
          write(g,q);
          i:=i+m ;
        end;
     end;
  CloseFile(f);
  CloseFile(g);
  Writeln;
 
  Reset(g);
  Writeln('Содержимое файла с транспонированной матрицей:');
  while not Eof(g) do
    begin
      read(g,q);
      Write(q:5:1);
      write(' ');
    end;
  CloseFile(g);
  Writeln;
 
  writeln('Матрица, сконструированная из исходного файла');
  print_matrix(f);
  Writeln;
 
  Writeln('Транспонированная матрица из файла');
  print_matrix(g);
  Readln;
end.
1
19.04.2012, 21:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.04.2012, 21:35
Помогаю со студенческими работами здесь

Запись данных в типизированный файл
program p1; uses crt; const d=10; type dann=record fio:string; pol:string; ...

Запись массива в типизированный файл
Программа должна по идее записать введённый с клавиатуры массив в типизированный (двоичный...

Запись в типизированный файл (dat)
Помогите пожалуйста, как записать информацию из 5 полей edit и 2 полей combobox, которые содержат...

Запись в типизированный файл из текстового
Здравствуйте. Необходимо создать типизированный файл из символов от &quot;А&quot; до &quot;Я&quot;: либо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru