Проблеммы с типом String

Вопросы программирования и использования среды Lazarus.

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

Проблеммы с типом String

Сообщение Кот239 » 02.08.2011 14:37:56

Код: Выделить всё
type

baza=record
s:string;
end;


var

bz:baza;
f:file of baza;



bz.s:='проверка';

AssignFile(f,'C:\111.dat');
Rewrite(f);
Write(f,bz);
CloseFile(f);



AssignFile(f,'C:\111.dat');
Reset(f);
Read(f,bz);
CloseFile(f);

Memo1.Lines.Add(bz.s);


при таком коде работает правильно. сохраняет 4 байтную переменную, при считывании отображается правильно без каких либо перекодировок, но выражении:

Код: Выделить всё
bz.s:=Memo1.Text;


ничего не получается. перебирал все возможные комбинации типа UTF8Decode/UTF8Encode, SysToUTF8 и т.п. ничего не помогает. хочется уже ради принципа узнать в чем дело
Кот239
незнакомец
 
Сообщения: 7
Зарегистрирован: 02.08.2011 14:05:24

Re: Проблеммы с типом String

Сообщение stikriz » 02.08.2011 16:11:42

Ну, а как Вы думаете что такое стринг? Не указатель-ли? И в структуре у Вас 4 байта указателя. Распределите память под строку перед использованием.
А если не нравится - используйте классы.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Проблеммы с типом String

Сообщение Кот239 » 02.08.2011 16:44:58

Возможно мой ответ покажется кому то тупым, я не очень силен в програмировании, однако очень озадачен вышеописаной проблемой уже не первую неделю ищу на форумах ответ и не нахожу.
Не совсем понимаю как именно указатель спасает ситуацию в данном случае. В любом случае при вводе в Memo текста он сохраняется 4байтной конструкцией. Однако в случае ввода текста в Memo эти 4 байта совершенно иные чем при присвоении переменной прямо в програме. Я грешил на то что из Memo мы получаем UTF8 а для кирилицы нужен WideString что многократно обсуждается в сети. Однако не смотря на все эксперементы успехом дело не увенчалось.
P.S. Прошу не злиться если говорю ерунду по незнанию, если можно в двух словах каким образом указатель положение?
И чем класс лучше записи?
Кот239
незнакомец
 
Сообщения: 7
Зарегистрирован: 02.08.2011 14:05:24

Re: Проблеммы с типом String

Сообщение tria » 02.08.2011 17:22:57

Для начала необходимо точное разъяснение слов "ничего не получается".
Иначе непонятно, чего там у вас не получается?

Прям из Масяньки :)
tria
постоялец
 
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10

Re: Проблеммы с типом String

Сообщение zub » 02.08.2011 17:37:19

Вам нужно либо использовать тип shortstring для s, либо по другому записывать в файл.

В данном случае вы пишите в файл не строку, а адрес этой строки в памяти. С 'проверка' работает потому что во время работы программы адрес этой строки в памяти не меняется, если вы прочитаете этот файл на другом компе - получите AV.

при таком коде работает правильно. сохраняет 4 байтную переменную

hint: строка 'проверка' занимает в памяти не 4 байта
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Проблеммы с типом String

Сообщение Sergei I. Gorelkin » 02.08.2011 17:59:48

Это было исправлено еще год и 8 месяцев назад, но до сих пор не попало в релиз-версию :(
Современный компилятор не позволяет объявлять файл, состоящий из управляемых типов.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Проблеммы с типом String

Сообщение Кот239 » 02.08.2011 18:08:47

zub писал(а):строка 'проверка' занимает в памяти не 4 байта

Любая вводимая строка до 256 символов записывается в файл 4 байтами.
zub писал(а):Вам нужно либо использовать тип shortstring для s, либо по другому записывать в файл.

Хорошо, как по другому в лазарусе сохранить текст не в текстовом файле а например file of string. Мне нужно именно не построчно а в структурном виде.

Добавлено спустя 2 минуты 10 секунд:
Sergei I. Gorelkin писал(а):Это было исправлено еще год и 8 месяцев назад, но до сих пор не попало в релиз-версию :(
Современный компилятор не позволяет объявлять файл, состоящий из управляемых типов.

Но ведь другие типы например byte, real работают! и только с файлами типа string возникают проблемы
Кот239
незнакомец
 
Сообщения: 7
Зарегистрирован: 02.08.2011 14:05:24

Re: Проблеммы с типом String

Сообщение VirtUX » 02.08.2011 19:27:38

Кот239 писал(а):Любая вводимая строка до 256 символов записывается в файл 4 байтами.

zub писал(а):вы пишите в файл не строку, а адрес этой строки в памяти

Вы знаете что такое указатели и адресация памяти? Если нет, то сначала изучите этот материал, а потом уже пробуйте дальше! Иначе мы не поймем друг-друга ;)
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Проблеммы с типом String

Сообщение Sergei I. Gorelkin » 02.08.2011 19:51:17

Кот239 писал(а):Хорошо, как по другому в лазарусе сохранить текст не в текстовом файле а например file of string. Мне нужно именно не построчно а в структурном виде.


Как уже было сказано, можно использовать shortstring (точнее, file of shortstring). Будет занимать по 256 байт на строку. Если так много не нужно, можно объявить тип покороче:
Код: Выделить всё
type
   mystring=string[31];
var
  f: file of mystring;


Кот239 писал(а):Но ведь другие типы например byte, real работают! и только с файлами типа string возникают проблемы

Слово 'string' может соответствовать двум совешенно разным типам: shortstring или ansistring. Shortstring представляет собой 256 байт, в которых хранятся непосредственно символы, и которые можно записать в типизированный файл и потом прочитать оттуда. Ansistring представляет собой 4-байтовый указатель на область хранения символов, который, будучи записан в файл, представляет собой просто мусор.

В Lazarus по умолчанию принимается string=ansistring, но его можно переключить на shortstring, вставив в начале программы {$H-}.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Проблеммы с типом String

Сообщение Maxizar » 02.08.2011 19:53:14

Кот239, а чем вас шортстринги не устраивают? Вам же Зуб сказал как можно строку сохранить....
скажем вот так все Ок.:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  bz:baza;
  f:file of baza;
begin
  bz.s:='1';

  AssignFile(f,'C:\111.dat');
  Rewrite(f);
  Write(f,bz);
  bz.s:='Много букв не ну очень много :))';
  Write(f,bz);
  CloseFile(f);

  AssignFile(f,'C:\111.dat');
  Reset(f);
  Read(f,bz);
  caption:=bz.s;
  Read(f,bz);
  CloseFile(f);

  caption:=caption +'   '+bz.s;
end;


Теперь теория:
когда вы пишите файл и хотите чтоб он был строгой конструкции, в данно случае конструкция = Record, то при записи и чтении компилятор должен знать сколько эта запись в длинну.

Но ведь другие типы например byte, real работают!

Это стандартные типы - которые имеют строгий и определенный размер, скажем байт ну он и в линуксе байт (что кстати очень удивительно).
Внимание вопрос: а чему ровна длина строки? типа String? ааа вот так-то...
Код: Выделить всё
S:String;
S:='1';
S:='12';
S:='123';
S:='1234567890';

А вот шортстринг имеет определенный размер, именно по этому мы можем его корректно прочитать и записать в двоичный файл, потому что компилятор знает сколько ему нужно прочитать-записать. А для стринга он не знает, потому что длина стринга разная.
Если вам длины ШортаСтринг мало, ну тут все что душе угодно, вплоть до массива из шортстрингов нужной вам длины.ну или скажем массива символов, думаю идея понятна.

Упс опередили... :D
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Проблеммы с типом String

Сообщение Vadim » 03.08.2011 05:33:19

Кот239 писал(а):ничего не получается.

Вы так и не написали, а что же именно у Вас "ничего не получается"? Это очень уж большой секрет или, может быть, Вы его всё же откроете заинтересованной общественности?
Вас надо понимать так, что Вы присваиваете своей переменной bz.s текст из пустого Мемо и героически ожидаете, что в переменной bz.s появится текста ровно на 4 байта? Я Вас правильно понял?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Проблеммы с типом String

Сообщение Кот239 » 03.08.2011 09:49:47

Всем большое спасибо за разжовывание материала о шортах вчастности, попрактикуюсь - сообщу о результатах.

Vadim писал(а):Вас надо понимать так, что Вы присваиваете своей переменной bz.s текст из пустого Мемо и героически ожидаете, что в переменной bz.s появится текста ровно на 4 байта? Я Вас правильно понял?

Да я что извращенец-теоретик что ли?! Я же несколько раз писал выше, что при присваивании любого текста из мемо он в отбратную нечитается, вместо символов непонятный набор байтов, который не в Ansi, не в UTF8 и не в какие двери не лезет. почему - мне уже дали понять выше.
Кот239
незнакомец
 
Сообщения: 7
Зарегистрирован: 02.08.2011 14:05:24

Re: Проблеммы с типом String

Сообщение stikriz » 03.08.2011 10:11:05

Кот239 писал(а):Да я что извращенец-теоретик что ли?! Я же несколько раз писал выше, что при присваивании любого текста из мемо он в отбратную нечитается, вместо символов непонятный набор байтов, который не в Ansi, не в UTF8 и не в какие двери не лезет. почему - мне уже дали понять выше.

Что такое
Код: Выделить всё
baza=record
s:string;
end;
?
Это кусок памяти размером, равным сумме размеров всех элементов, входящих в него. Сделайте Sizeof(baza). Что получилось? 4 байта?
Попробуйте объявить так:
Код: Выделить всё
baza=record
s:string[50];
end;

Сделайте Sizeof(baza). Что получилось? 50 байт?
Если теперь непонятно, то объяснить невозможно.
Аватара пользователя
stikriz
энтузиаст
 
Сообщения: 612
Зарегистрирован: 15.03.2006 09:37:47

Re: Проблеммы с типом String

Сообщение Кот239 » 03.08.2011 10:55:35

Да понятно..более чем. Спасибо. Рассказали именно в тему.
Кот239
незнакомец
 
Сообщения: 7
Зарегистрирован: 02.08.2011 14:05:24

Re: Проблеммы с типом String

Сообщение Кот239 » 06.08.2011 12:53:14

Кстати..возник еще один вопрос на данную тему. А возможно ли в процессе выполнения программы изменить зарезервированую длину строчной переменной? С целью экономии места при записи в файл естественно.
Насколько я понимаю функция SetLength просто изменяет значение нулевого байта в строке сообщая сколько у нас записано символов, а заданый диапазон в переменной так и остается.
Кот239
незнакомец
 
Сообщения: 7
Зарегистрирован: 02.08.2011 14:05:24

След.

Вернуться в Lazarus

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

Сейчас этот форум просматривают: Google [Bot] и гости: 14

Рейтинг@Mail.ru