Проблема со struct!
При вызове функции появляется сообщение об ошибке
"Access violation at address".
{
int intWidth;
int intHeight;
string chrSkin;
} sMainSettings;
void ReadSettings(sSettings* p)
{
string strLine;
char* chrLine;
int intTest;
ifstream inFile ("settings.txt");
if(inFile.is_open())
{
inFile.seekg(0);
inFile.getline(chrLine, 100);
p->intHeight = StrToInt(chrLine);
inFile.getline(chrLine, 100);
p->intWidth = StrToInt(chrLine);
inFile.getline(chrLine, 100);
p->chrSkin=chrLine;
inFile.close();
}
}
Вызов функции такой:
Подскажите, пожалуйста, в чем проблема.
Green конечно посоветует еще раз прочитать Страуструпа.
Очень информативный ответ.
Очень информативный ответ.
Спасибо. Наверное, надо так:
char chrLine[100];
...
Спасибо. Наверное, надо так:
char chrLine[100];
...
Спасибо REmindER!
Теперь все идет без ошибок.
Не знаю структуры файла, но лучше сделать так:
{
ifstream inFile("settings.txt");
if( inFile.is_open() )
{
inFile >> settings.intHeight;
inFile >> settings.intWidth;
inFile >> settings.chrSkin;
inFile.close();
}
}
А ещё можно определить operator >> для структуры sSettings.
Может, действительно, перечитать Страуструпа... ;)
Не знаю структуры файла, но лучше сделать так:
{
ifstream inFile("settings.txt");
if( inFile.is_open() )
{
inFile >> settings.intHeight;
inFile >> settings.intWidth;
inFile >> settings.chrSkin;
inFile.close();
}
}
А ещё можно определить operator >> для структуры sSettings.
Я пробовал считывать таким методом
inFile >> settings.chrSkin;, но текст считывается только до первого пробела. Поэтому и искал альтернативу. Правда использовал char*, а не char[]. Спасибо за идею.
Я пробовал считывать таким методом
inFile >> settings.chrSkin;, но текст считывается только до первого пробела. Поэтому и искал альтернативу. Правда использовал char*, а не char[]. Спасибо за идею.
Все равно, можно обойтись без C-style строк в программе на C++. Например, так:
Все равно, можно обойтись без C-style строк в программе на C++. Например, так:
Но тогда надо тип поменять в struct.
Со string на char[], а то в getline char* или char подавать надо.
Но тогда надо тип поменять в struct.
Со string на char[], а то в getline char* или char подавать надо.
Ничего менять не надо.
Смотри определение std::getline
basic_istream<CharType, Traits>& getline(
basic_istream<CharType, Traits>& _Istr,
basic_string<CharType, Traits, Allocator>& _Str
);
template<class CharType, class Traits, class Allocator>
basic_istream<CharType, Traits>& getline(
basic_istream<CharType, Traits>& _Istr,
basic_string<CharType, Traits, Allocator>& _Str,
CharType _Delim
);
Ничего менять не надо.
Смотри определение std::getline
basic_istream<CharType, Traits>& getline(
basic_istream<CharType, Traits>& _Istr,
basic_string<CharType, Traits, Allocator>& _Str
);
template<class CharType, class Traits, class Allocator>
basic_istream<CharType, Traits>& getline(
basic_istream<CharType, Traits>& _Istr,
basic_string<CharType, Traits, Allocator>& _Str,
CharType _Delim
);
У меня в C++ Builder 6 выдаёт такую ошибку:
У меня в C++ Builder 6 выдаёт такую ошибку:
Будь внимательнее, обрати внимание, что я говорю о функции std::getline, а ты о методе istream::getline.
Видимо ты пишешь
inFile.getline(settings.chrSkin);
а надо писать
getline(inFile, settings.chrSkin);
Там есть другая загвоздка... :)
Но о ней позднее, когда у тебя всё скомпилируется и запуститьститься.
Вот читаю и думаю, а зачем этот вопрос в топике по CBuilder? Конечно stl никто не отменял, но если вопрос всетаки о Borland C++, то для сохранения и восстановления начальных значений существует специальный класс TIniFile. Да и чтение лучше делать функцией FileRead.
Вот и примерчик:
{
TIniFile *ini;
ini = new TIniFile( ChangeFileExt( Application->ExeName, ".INI" ) );
Top = ini->ReadInteger( "Form", "Top", 100 );
Left = ini->ReadInteger( "Form", "Left", 100 );
Caption = ini->ReadString( "Form", "Caption",
"Default Caption" );
ini->ReadBool( "Form", "InitMax", false ) ?
WindowState = wsMaximized :
WindowState = wsNormal;
delete ini;
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
TIniFile *ini;
ini = new TIniFile(ChangeFileExt( Application->ExeName, ".INI" ) );
ini->WriteInteger( "Form", "Top", Top );
ini->WriteInteger( "Form", "Left", Left );
ini->WriteString ( "Form", "Caption", Caption );
ini->WriteBool ( "Form", "InitMax",
WindowState == wsMaximized );
delete ini;
}
В фал будет записано:
[Form]
Top=185
Left=280
Caption=Default Caption
InitMax=0
Будь внимательнее, обрати внимание, что я говорю о функции std::getline, а ты о методе istream::getline.
Видимо ты пишешь
inFile.getline(settings.chrSkin);
а надо писать
getline(inFile, settings.chrSkin);
Там есть другая загвоздка... :)
Но о ней позднее, когда у тебя всё скомпилируется и запуститьститься.
А этот вариант сохраняет текущую позицию в файле?
Или это и есть загвоздка :) ?
Вот и примерчик:
{
TIniFile *ini;
ini = new TIniFile( ChangeFileExt( Application->ExeName, ".INI" ) );
Top = ini->ReadInteger( "Form", "Top", 100 );
Left = ini->ReadInteger( "Form", "Left", 100 );
Caption = ini->ReadString( "Form", "Caption",
"Default Caption" );
ini->ReadBool( "Form", "InitMax", false ) ?
WindowState = wsMaximized :
WindowState = wsNormal;
delete ini;
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
TIniFile *ini;
ini = new TIniFile(ChangeFileExt( Application->ExeName, ".INI" ) );
ini->WriteInteger( "Form", "Top", Top );
ini->WriteInteger( "Form", "Left", Left );
ini->WriteString ( "Form", "Caption", Caption );
ini->WriteBool ( "Form", "InitMax",
WindowState == wsMaximized );
delete ini;
}
В фал будет записано:
[Form]
Top=185
Left=280
Caption=Default Caption
InitMax=0
Спасибо за инфу, но с текстовым файлом наверно быстрее будет работать.
А stl тут при чем?