Schumi |
Отправлено: 08.10.2003, 12:23 |
|
Машинист паровоза
Группа: Участник
Сообщений: 206
|
Есть у проги INI-файл. Я записываю туда все настройки,в том числе и строку.
Сперва int-указывает длину строки,а потом саму строку.
Записывается в файл нормально,а при считывании в конце иногда дописывается какая-та гадость.
Храню в памяти строку -в виде AnsiString,а записваю *char,используя метод c_str().
Может быть нужно при считывании,последний байт делать 0?
CODE |
//save
AnsiString Name=BaseForm->LastDir;
Int=Name.Length();
FileWrite(Handle,&Int,sizeof(Int));
FileWrite(Handle,(void*)Name.c_str(),Name.Length());
//load
FileRead(Handle,&Int,sizeof(Int));
char str=new char[Int+1];
FileRead(Handle,str,Int);
BaseForm->LastDir=StrPas(str);
|
|
|
Admin |
Отправлено: 08.10.2003, 13:12 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
CODE |
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString Name = Edit1->Text;
int Int = Name.Length();
int ih = FileCreate("myFile.ini");
FileWrite(ih,&Int,sizeof(Int));
FileWrite(ih,(void*)Name.c_str(),Name.Length());
FileClose(ih);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int Int;
int ih = FileOpen("myFile.ini",fmOpenRead);
FileRead(ih,&Int,sizeof(Int));
char* str = new char[Int+1];
for(int i=0; i<Int+1; i++) str[i] = 0;
FileRead(ih,str,Int);
FileClose(ih);
AnsiString s = str;
ShowMessage(s);
delete []str;
}
//----------------------------------------------------
|
Вроде работает.
Может дело в
CODE |
char* str = new char[Int+1];
for(int i=0; i<Int+1; i++) str[i] = 0;
|
Отредактировано Admin — 08/10/2003, 14:15
|
|
Георгий |
Отправлено: 08.10.2003, 21:23 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
Может я не по теме, но использовал я TIniFile, что и тебе Schumi могу посоветовать. Хотя не зная всех особенностей твоей задачи не могу утверждать, что он тебе подойдёт.
|
|
Schumi |
Отправлено: 09.10.2003, 10:24 |
|
Машинист паровоза
Группа: Участник
Сообщений: 206
|
Admin:ты прав,если обнулять сперва все байты — всё ок.Но это как-то неправильно.Ведь,по хорошему,мы выделили память: значения в байтах левые,но последний та нулевой должен быть,и при считывании из файла должно проходить.
Георгий: IniFiles — вещь хорошая,но понимаешь,пользователь сможет его довольно легко редактитровать вручную. (всё-таки поля key будут обзываться по смыслу).А так вроде,открываешь,а там двоичный файл,в перемешку с отрывками слов.Как бы и сложнее.
И ещё вопрос:а как загрузить весь файл в память,видимо char *buf — не подходит,если в файле встречаются нулевый байты (обрежется),нужно что,void,а как потом обращаться с элементами,копировать определённые блоки?
|
|
Георгий |
Отправлено: 09.10.2003, 21:38 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
был такой способ (это о загрузке всего файла в память):
CODE | #pragma pack ( push, 1 );
struct IniFileData
{
int Field1;
char Field2[32];
float Field3;
};
#pragma pack ( pop );
void __fastcall TForm1::Button1Click(TObject *Sender)
{
IniFileData data1,data2;
HANDLE hFile;
DWORD t;
hFile=CreateFile("c:\\test.bin",GENERIC_READ|GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);
//установка конфигурации
data1.Field1=13;
strncpy(data1.Field2,"test string",sizeof(data1.Field2));
data1.Field3=13.666;
//запись конфигурации
WriteFile(hFile,&data1,sizeof(data1),&t,0);
SetFilePointer(hFile,0,0,FILE_BEGIN);
// чтение конфигурации
ReadFile(hFile,&data2,sizeof(data2),&t,0);
CloseHandle(hFile);
} |
Суть его в том, что бы объявить структуру фиксированного размера, которую писать в файл и читать.
Кстати — по устойчивости ко взлому оба варианта (TIniFile vs обычный бинарный файл) эквивалентны, но если "обычный бинарный файл" можно превратить в "обычный шифрованный бинарный файл", то с TIniFile это так просто не пройдет — придётся делать своего потомка от него и в нём реализовывать шифрование. |
|
|