Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Странная ошибка


Автор: Serik 22.12.2006, 15:59
Код

procedure TForm3.zapisClick(Sender: TObject);
var
l:integer;
begin
tempmas[1]:=registration.text;
tempmas[2]:=numb_ishod.text;
tempmas[3]:=  nicks .text;
tempmas[4]:=   docum_name .text;
tempmas[5] :=   index.text;
tempmas[6] :=  adres.text;
tempmas[7] :=   ispolnit.text;
tempmas[8] :=    index_komp.text;
tempmas[9] :=      ind_komp.text;
  try
     stream:= tfilestream.Create('nomber.dat',fmopenreadwrite);
  stream.seek(0, soFromBeginning);
  stream.read(temp[1],10);
  nomber:=strtoint(temp[1]);
   edit1.Text:=temp[1];
    finally
  stream.Free;
  end;
    nomber:=nomber+1;
  temp[1]:=inttostr(nomber);
  edit3.text:= temp[1];
   try
    stream:= tfilestream.Create('nomber.dat',fmopenreadwrite);
   stream.seek(0, soFromBeginning);
   stream.write(temp[1],10);
    stream.seek(0, soFromBeginning);
   stream.read(temp[1],10);
     finally
  stream.Free;

   edit2.Text:=temp[1];

end;
end;

значит программа запускается, а потом как запускаю эту процеДУРУ выдается ошибка не подскажете где ошибся, помоеиу что-то с типами, но что?

Автор: Matematik 22.12.2006, 16:08
Цитата(Serik @  22.12.2006,  15:59 Найти цитируемый пост)
выдается ошибка

Какая?

Автор: Serik 22.12.2006, 16:16
user posted image
а потом
user posted image

Автор: Matematik 22.12.2006, 16:30
Что такое "tempmas" и "temp"?

Автор: Serik 22.12.2006, 16:32
Это масивы типа стринг

Автор: MetalFan 22.12.2006, 16:34
бредовый кусок.
или это не весь код?

Автор: Serik 22.12.2006, 16:35
конечно не весь!!! smile , там по середине должен быть еще довольно большой, но я его временно закры, чтоб проверить этот!

Автор: MetalFan 22.12.2006, 17:04
давай описание типов переменных

Автор: Serik 22.12.2006, 17:11
Код

type
  TForm3 = class(TForm)
   registration: TLabeledEdit;
    numb_ishod: TLabeledEdit;
    nicks: TLabeledEdit;
    docum_name: TLabeledEdit;
    index: TLabeledEdit;
    adres: TLabeledEdit;
    ispolnit: TLabeledEdit;
    index_komp: TLabeledEdit;
    ind_komp: TLabeledEdit;
    zapis: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;

    procedure zapisClick(Sender: TObject);
  private
    var

    a,b: string;
    k,c:string;
    d:char;
    stream:tfilestream;
    nomber:integer;
     temp: array[0..100] of string;
      tempmas: array[0..9] of string;
      { Private declarations }
  public
    F: textfile;{ Public declarations }
    mas: array[1..11,1..100] of string;
  end;

var
  Form3: TForm3;

implementation


Автор: MetalFan 22.12.2006, 18:11
  SetLength(temp[1], 10 );
   stream.seek(0, soFromBeginning);
   stream.write(temp[1][1],10);
    stream.seek(0, soFromBeginning);
   stream.read(temp[1][1],10);

так должно работать по идее)

Автор: Serik 23.12.2006, 19:15
не получилось

Автор: Matematik 23.12.2006, 19:26
Что не получилось? 
Какой код не работает? 
Пиши весь код.
А так ошибка в 17 строке.

Добавлено @ 19:30 
MetalFan правильно на ошибку указал

Автор: MetalFan 23.12.2006, 19:33
Цитата(Serik @  23.12.2006,  19:15 Найти цитируемый пост)
не получилось 

где теперь ошибка? что не получилось?
я непойму, КОМУ тут нужна помощь? почему из тебя должны доп.информацию клещями вытягивать?!  smile 
з.ы. 99% на StrToInt валится)

Автор: Beltar 23.12.2006, 19:35
Можно я свои 5 копеек вставлю. При чтении в строку да и в массивы тоже, очень неплохо бы ее длину сначала задать с помощью SetLength. И читать примерно вот так:
Код

SetLength(s,TempInt);
FStream.ReadBuffer(Pointer(s)^,TempInt);


От всяких Access Violation помогает.

Автор: MetalFan 23.12.2006, 19:37
Цитата(MetalFan @  22.12.2006,  18:11 Найти цитируемый пост)
SetLength(temp[1], 10 );
stream.read(temp[1][1],10);



Цитата(Beltar @  23.12.2006,  19:35 Найти цитируемый пост)
SetLength(s,TempInt);
FStream.ReadBuffer(Pointer(s)^,TempInt);


те же яйца, только сбоку ;)

Автор: Beltar 24.12.2006, 15:02
Нифига, нужно преобразование к Pointer. Я тоже когда-то в это вперся и долго не мог понять что за фигня, спасибо одному знакомому программеру, объяснил.

Автор: MetalFan 24.12.2006, 15:53
Цитата(Beltar @ 24.12.2006,  15:02)
Нифига, нужно преобразование к Pointer. Я тоже когда-то в это вперся и долго не мог понять что за фигня, спасибо одному знакомому программеру, объяснил.


Фига!
и чтож он тебе объяснил?!

1) FStream.read(str[1] ,lLength);
и
2) FStream.ReadBuffer(Pointer(str)^,lLength);
где str: string, lLength: integer...
АБСОЛЮТНО идентичны по результату, 
только в 1) не делается проверка, прочиталось ли необх.кол-во байт в в буфер,
а в 2) в случае, если будет прочитано кол-во байт <> lLength, то получим исключение 'Stream read error'. да и подход немного поизвращенней получается... имхо 1) более наглядный.

Автор: Beltar 24.12.2006, 18:34
Извиняюсь. Дабы не вносить путаницы я не поленился найти то обсуждение, и проблемный код там был таким:
Код

FStream.ReadBuffer(TempInt,4);
FStream.ReadBuffer(NodeDesc.Text,TempInt);


Ответ был таким.

во первых, кто будет длину выставлять? аццес виолатион схватишь без
проблем. Там же указатель на область памяти и длина этой области. Сама
процедура чтения не заботится о выделении памяти. Во вторых что Read
что Save работают не со стрингами а с PChar. Можно, конечно более
криво сделать как ты сделал - NodeDesc.Text[1]. Но это не совсем
правильно, и в теории если сменится версия компилятора то ты будешь
ловить баги, которые сложно поймать. Надо переводить в PChar -
"красивой конструкцией" Pointer(String)^ ибо PChar(String) может
глюкануть. ну или грузить в какой ниить Array of Char а потом через
StrPas(TArrayOfChar) переводить в String.


С указанием первого элемента массива действительно будет работать. А вот записывать надо через указатель, иначе попа.

Кстати, а что записывается в проблемный файл посмотреть каким-нибудь Windows commander'ом пробовали? Англ. буквы им хорошо видны. Может там лажа просто.

Вот экземпл. Просто записывыет из эдита в файл текст и считывает его. Можете экспериментировать.

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FStream:TStream;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var S:String;
begin
S:=Edit1.Text;
try
FStream:=TFileStream.Create('File.dat',fmCreate or fmShareDenyRead);
FStream.Seek(0,soFromBeginning);
FStream.WriteBuffer(Pointer(S)^,Length(S));
finally
FStream.Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var S:String;
begin
try
FStream:=TFileStream.Create('File.dat',fmOpenRead or fmShareDenyWrite);
FStream.Seek(0,soFromBeginning);
SetLength(S,FStream.Size);
FStream.ReadBuffer(Pointer(s)^,FStream.Size);
Label1.Caption:=S;
finally
FStream.Free;
end
end;

procedure TForm1.Button3Click(Sender: TObject);
var S:String;
begin
try
FStream:=TFileStream.Create('File.dat',fmOpenRead or fmShareDenyWrite);
FStream.Seek(0,soFromBeginning);
SetLength(S,FStream.Size);
FStream.ReadBuffer(s[1],FStream.Size);
Label1.Caption:=S;
finally
FStream.Free;
end
end;

end.

Автор: MetalFan 24.12.2006, 19:16
мда. притянутые за уши аргументы.
про выделение памяти - это понятно. а вот остальное - безосновательные доводы, имхо.
PChar(String) может глюкануть 
ну-ну, а 
Pointer(String)^ 
не может? да что угодно может, если ручки неоттуда растут ;)

ну или грузить в какой ниить Array of Char а потом через
StrPas(TArrayOfChar) переводить в String.

StrPas вообще можно не использовать - функция-пустышка для обратной совместимости. (по крайней мере с D6)

Код

var
  lFS: TFileStream;
  lStr: string;
  lLen: Integer;
begin
  try
    lFS := TFileStream.Create( 'c:\test.txt', fmCreate );
  except
    Exit;
  end;
  try
    lStr := 'test тест';
    ShowMessage(lStr);
    lLen := length( lStr );
    lFS.Write( lstr[1], lLen );
    lFS.Seek(0, soFromBeginning);
    lFS.read( lStr[1], lLen );
    ShowMessage(lStr);
  finally
    lFS.Free;
  end;

все отрабтывает без проблем. и запись и чтение. так что ненадо "воду мутить" )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)