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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.05.2011, 08:07   #1
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию string и TMemoryStream

строка это что? последовательность символов!
а TMemoryStream это что? тоже последовательность символов! (или нет?)
как строку запихнуть в TMemoryStream?

и еще один вопрос по поводу TMemoryStream.
что такое buffer?
почти все функции работы с TMemoryStream просят это,
но нигде не написано что это такое =(

только не баньте плиз, если вдруг такая тема уже есть.
я не нашел.
xrob вне форума Ответить с цитированием
Старый 20.05.2011, 08:35   #2
SERG1980
Участник клуба
 
Аватар для SERG1980
 
Регистрация: 28.03.2007
Сообщений: 1,814
По умолчанию

Я например для записи строки в мемористрим использую стрингстрим
запись в файл строки
Код:
procedure TForm1.Button1Click(Sender: TObject);
var MS:TMemoryStream;
    SS:TStringStream;
    s:string;
begin
 s:='qwert';
 SS:=TStringStream.Create('');
 SS.WriteString(s);
 SS.Seek(0,0);
 MS:=TMemoryStream.Create;
 MS.CopyFrom(SS,SS.Size);
 MS.SaveToFile('d:\1.txt');
 FreeAndNil(MS);
 FreeAndNil(SS);
end;
чтение из файла строки
Код:
procedure TForm1.Button3Click(Sender: TObject);
var MS:TMemoryStream;
    SS:TStringStream;
    s:string;
begin
 MS:=TMemoryStream.Create;
 MS.LoadFromFile('d:\1.txt');
 MS.Seek(0,0);
 SS:=TStringStream.Create('');
 SS.CopyFrom(MS,MS.Size);
 s:=SS.DataString;
 showmessage(s);
 FreeAndNil(MS);
 FreeAndNil(SS);
end;
SERG1980 вне форума Ответить с цитированием
Старый 20.05.2011, 08:43   #3
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> тоже последовательность символов! (или нет?)

скорее последовательность байт

> что такое buffer?

любые данные

> но нигде не написано что это такое =(

даже если Ф1 нажать? не верю )

краткий курс по записи в поток:

Код:
var
  ms: TMemoryStream;
  s: string;
  i: Integer;
  p: Pointer;
begin
  ms := TMemoryStream.Create();
  try
    //
    s := 'Put me into memory stream, please.';
    ms.Write(s[1], length(s) * sizeof(s[1]));
    //
    i := 1234;
    ms.Write(i, sizeof(i));
    //
    GetMem(p, 1024);
    FillChar(p^, 1024, #0);
    ms.Write(p^, 1024);
    //
    i := ms.size;
  finally
    FreeMem(p);
    FreeAndNil(ms);
  end;
end;
Чтение аналогично, только в другую сторону.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 20.05.2011, 09:41   #4
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

сделал как написал SERG1980 =)
все работает, всем спасибо!

и я не очень понял, что мы делаем вот этой строчкой:
ms.Write(s[1], length(s) * sizeof(s[1])); ?

мы передаем в функцию первый символ строки и длину строки * размер первого символа (?)
это вы для наглядности написали?
насколько я понял length(s) * sizeof(s[1]) это сколько памяти нужно выделить для строки?
sizeof(s[1]) - это что? здесь мы определяем размер одного символа??? 1 байт. всегда. (или я не прав?)

и если можно, veniside, прокомментируйте, пожалуйста ваш код?
а то что это такое
ms.Write(s[1], length(s) * sizeof(s[1]));
я еще понял,
но все последующее, не понимаю зачем нужно...

Последний раз редактировалось xrob; 20.05.2011 в 09:49.
xrob вне форума Ответить с цитированием
Старый 20.05.2011, 10:33   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
но все последующее, не понимаю зачем нужно...
Это примеры, как можно записать в поток различные типы данных!


Цитата:
Чтение аналогично, только в другую сторону.
ну, если в потоке ничего больше, кроме записанной строки нет - тогда действительно, прочитать строчку из потока проблем не вызовет (только не забыть сделать предварительно setLength(s, ms.Size);

А вот если в потоке несколько строк (или несколько различных данных/структур), тогда с определением длины строки возникнут огромные сложности.

я, если надо в поток(файл) сохранить строку предварительно пишу в поток(файл) длину.

ну, примерно так:
Код:
    s := 'Put me into memory stream, please.';
    ms.Write(length(s), sizeof(integer);
    ms.Write(s[1], length(s) * sizeof(s[1]));
Serge_Bliznykov вне форума Ответить с цитированием
Старый 20.05.2011, 11:10   #6
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Думаю, важно упомянуть, что тип string по умолчанию в дельфи это не shortstring а ansistring , указатель на строку, и чтобы записать её данные, а не сам указатель, надо её "разыменовать", а делается это посредством обращения к первому символу, ну а количество байт для записи из строки определяем функцией length .

Насчет sizeof(s[1]) - это для гибкости кода (для последующей поддержки проектов) - потому как с дельфи 2009 (вроде) стандартный тип string уже является unicode widestring и размер одного символа - 2 байта.

При чтении , как написал Serge, удобно считывать размер прямо из файла (тогда надо его туда записать), хотя можете исхитриться использовать маркер конца строки - свой или #0 (тут правда придётся посимвольно считывать)
phomm вне форума Ответить с цитированием
Старый 20.05.2011, 11:54   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

phomm, согласен со всем сказанным.

но хочу сделать одно маленькое уточнение (для изучающих работу с сохранением строки)
Цитата:
Сообщение от phomm
хотя можете исхитриться использовать маркер конца строки - свой или #0 (тут правда придётся посимвольно считывать)
Только надо отметить, что сам по себе этот самый маркер в потоке не появится!
Т.е. его туда надо записать (хоть свой, хоть #0)...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 21.05.2011, 10:41   #8
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

а у меня такой вопрос.
если какой-то файл создан с использованием всех 256 символов, в том числе и #0,
то такой файл категорически не сочетается с PChar?

и еще, string это указатель???
т.е. когда я передаю в функцию bugoga(str:string):integer; то я передаю указатель?
а что тогда такое str[5]; ? указатель на пятый символ строки?
а str[3]:='d'; получается указателю присваиваю значение типа char?

и еще вопрос, ответить можно в формате boolean:
PChar - это указатель на первый символ строки, которая оканчивается #0 ?

т.е. чтобы получить PChar нужно
str:=str+#0;
PChar:=@str[1];
так?
xrob вне форума Ответить с цитированием
Старый 21.05.2011, 21:22   #9
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

да простит меня GunSmoker за сие...
ответ на поставленные вопросы - http://www.transl-gunsmoker.ru/2009/09/pchars.html
phomm вне форума Ответить с цитированием
Старый 22.05.2011, 11:22   #10
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

Цитата:
Текст строковых констант хранится где-то в программе (и имеет терминатор #0)
я теперь понял, что это был за железный робот из будущего! =)
терминатор! он должен был что-то завершить!
за сцылку спасибо.
xrob вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
string, TMemoryStream, TBitmap и я xrob Свободное общение 5 20.05.2011 09:01
IdHTTP и TMemoryStream и String syserg Работа с сетью в Delphi 2 02.04.2010 20:31
TMemoryStream Владимир1988 Помощь студентам 0 13.02.2010 13:04
Как получить адрес String строки или преобразовать String madboy4ik Общие вопросы по Java, Java SE, Kotlin 6 15.01.2010 11:57