Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Странная ошибка 
:(
    Опции темы
Beltar
Дата 24.12.2006, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 3
Всего: 7



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


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
MetalFan
Дата 24.12.2006, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(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) более наглядный.

Это сообщение отредактировал(а) MetalFan - 24.12.2006, 15:53


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Beltar
Дата 24.12.2006, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 3
Всего: 7



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

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.



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
MetalFan
Дата 24.12.2006, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



мда. притянутые за уши аргументы.
про выделение памяти - это понятно. а вот остальное - безосновательные доводы, имхо.
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;

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

Это сообщение отредактировал(а) MetalFan - 24.12.2006, 19:17


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1216 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.