Запись и чтение String из нетипизированного файла

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Запись и чтение String из нетипизированного файла

Сообщение Ferrum » 07.07.2010 13:03:02

При работе со строками:
SizeOf(переменная) выдаёт 0
Length(переменная) выдаёт количество символов в строке

Что и как надо указать в третьем параметре BlockRead/BlockWrite, чтобы строку можно было нормально записать и считать из нетипизированного файла?
И почему при записи в файл строки Ansi получаются не нормальные буквы, а иероглифы? В строке только латинские символы.
Аватара пользователя
Ferrum
новенький
 
Сообщения: 14
Зарегистрирован: 27.08.2009 10:11:53

Re: Запись и чтение String из нетипизированного файла

Сообщение Light13 » 07.07.2010 13:08:36

покажите как пишите

может стоит так
Write(StringVarible[1], Size);
Аватара пользователя
Light13
постоялец
 
Сообщения: 127
Зарегистрирован: 17.07.2009 07:50:10
Откуда: Челябинск

Re: Запись и чтение String из нетипизированного файла

Сообщение Ferrum » 07.07.2010 16:14:47

может стоит так
Write(StringVarible[1], Size);

Нет, для нетипизированных файлов используются свои процедуры, в которых самому надо указывать, сколько байт в какую переменную надо считать.
Код: Выделить всё
procedure WriteToMyFile;
var
  f: File;
  b: Byte;
begin
  AssignFile(f, fname);
  Rewrite(f, 1);

  BlockWrite(f, FWidth, SizeOf(FWidth));
  BlockWrite(f, FHeight, SizeOf(FHeight));
  b := Length(FString);
  BlockWrite(f, b, SizeOf(b));
  BlockWrite(f, FString, b);

  CloseFile(f);
end;


тут у меня есть переменные, объявленные вне процедуры
Код: Выделить всё
FWidth, FHeight: Single;
FString: String;


проблема в том, чтобы определить размер в байтах строковой переменной для последующей записи/чтения из нетипизированного файла. По идее его нужно получать так:
Код: Выделить всё
b := SizeOf(FSring);

но эта функция выдаёт 0 при работе с типом String и 4 при работе с AnsiString вне зависимости от реальной длины строки
В коде я специально записываю в файл переменную b, в которой хранится вычесленный размер строковой переменной, чтобы при чтении определить размер строки и правильно её считать. Но каким образом можно получить верный пазмер строки в байтах?
Последний раз редактировалось Ferrum 07.07.2010 16:20:34, всего редактировалось 1 раз.
Аватара пользователя
Ferrum
новенький
 
Сообщения: 14
Зарегистрирован: 27.08.2009 10:11:53

Re: Запись и чтение String из нетипизированного файла

Сообщение Дож » 07.07.2010 16:15:14

Код: Выделить всё
L := Length(S);
BlockWrite(F, L, SizeOf(L));
BlockWrite(F, S[1], L * SizeOf(S[1]));

BlockRead(F, L, SizeOf(L));
SetLength(S, L);
BlockRead(F, S[1], L * SizeOf(S[1]));
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Запись и чтение String из нетипизированного файла

Сообщение Ferrum » 07.07.2010 16:22:53

а почему S[1]? так ведь запишется только первый символ строки
Аватара пользователя
Ferrum
новенький
 
Сообщения: 14
Зарегистрирован: 27.08.2009 10:11:53

Re: Запись и чтение String из нетипизированного файла

Сообщение Mr.Smart » 07.07.2010 16:37:57

бррр
Код: Выделить всё
BlockWrite(f, FWidth[1], Length(FWidth));

В данном случае тип AnsiString является указателем на цепочку символов
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Запись и чтение String из нетипизированного файла

Сообщение Putnick » 07.07.2010 17:28:10

Ferrum писал(а):а почему S[1]? так ведь запишется только первый символ строки

Нет, так запишутся все символы (а вернее, указанное количество) начиная с первого. В противном случае Вы запишите указатель на свою строку. Как вариант, можно использовать так сказать "классические паскалевские" строки типа shortstring.
Тогда можно так:
Код: Выделить всё
BlockWrite(f,s,length(s)+1);
в получившейся записи первый (нулевой) байт — длина строки, последующие — собственно текст.
Putnick
новенький
 
Сообщения: 62
Зарегистрирован: 18.03.2009 13:02:56

Re: Запись и чтение String из нетипизированного файла

Сообщение Timid » 07.07.2010 21:55:59

shortstring = array [1..255] of AnsiChar;

Файл в такое не запишешь :)
Timid
постоялец
 
Сообщения: 290
Зарегистрирован: 21.11.2007 21:33:15

Re: Запись и чтение String из нетипизированного файла

Сообщение Vadim » 08.07.2010 04:51:24

Ferrum
А Вы используйте тип ShortString с предопределённым количеством символов:
Код: Выделить всё
Type
  TMyString: ShortString[20];

Если все буквы английские, то каждый символ занимает ровно 1 байт. Тут и получается, что размер заранее известен - делайте с ним что хотите.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Запись и чтение String из нетипизированного файла

Сообщение Ferrum » 08.07.2010 13:22:52

Vadim, предопределять кол-во символов не имею права: строка заполняется в процессе работы программы и её размер заранее неизвестен.
Putnick, спасибо за совет. Я думал, что работа с AnsiString не отличается от работы с классическими строками. Я так понимаю
{$H+} включает режим, когда тип String = AnsiString, {$H-} - String = ShortString.
Ранее ни c AnsiString, ни с ShortString дел не имел, писал просто String.
Я эммигрант с TP7 :mrgreen: Учился по учебнику Фаронова, там про такое не сказано.
А PChar и AnsiString это одно и то же?
Аватара пользователя
Ferrum
новенький
 
Сообщения: 14
Зарегистрирован: 27.08.2009 10:11:53

Re: Запись и чтение String из нетипизированного файла

Сообщение Putnick » 08.07.2010 14:01:01

Ferrum писал(а):А PChar и AnsiString это одно и то же?

Не совсем :wink:
Если коротко, то AnsiString, более сложно реализован, имеет счётчик ссылок, хранит длину строки. PChar — просто указатель на последовательность символов, завершающуюся символом с кодом #0.
Более подробно:http://easyprog.ru/index.php?option=com_content&task=view&id=218&Itemid=35
Putnick
новенький
 
Сообщения: 62
Зарегистрирован: 18.03.2009 13:02:56

Re: Запись и чтение String из нетипизированного файла

Сообщение Дож » 09.07.2010 01:22:47

а почему S[1]?

В памяти символы начинаются с S[1] и идут последовательно.
так ведь запишется только первый символ строки

Для верности, конечно, можно навесить что-то в стиле (@(S[1]))^. Но и так должно работать.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru