Piszę w Qt coś jak menadżer plików *.ini wszystko jest zamknięte w klasie:
namespace FNC
{
class IniFile
{
public:
IniFile();
void Open( QString FileName );
void Save( QString FileName );
QString GetValue( QString Section, QString Key );
void WriteValue( QString Section, QString Key, QString Value = "=EMPTY=");
QString GetSectionsNames( QString separator );
QString GetKeysNames( QString Section, QString separator );
private:
QStringList Sections;
QStringList Keys;
QStringList Values;
QString EMPTY();
};
}
a to definicje funkcji:
using namespace FNC;
QString ini(QString c)
{
return FNC::Coder::Text2FNI( c, FNC::Ini );
}
IniFile::IniFile()
{
}
void IniFile::Open( QString FileName )
{
QFile file(FileName);
if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) return;
QTextStream ts(&file);
QString line, lastSection;
for(; line != "end"; line = FNC::Coder::FNI2Text( ts.readLine(), FNC::Ini ) )
{
if(line.isEmpty()) continue;
if(line[0] == '#') continue;
if( line[0] == '[' )
{
line.remove( QChar('['), Qt::CaseInsensitive );
line.remove( QChar(']'), Qt::CaseInsensitive );
Sections << line;
lastSection = line;
Keys << EMPTY();
Values << EMPTY();
}
else
{
line.replace( QString("="), QString(" ") );
QStringList podzial = line.split( QRegExp("\\W+"), QString::SkipEmptyParts );
Sections << lastSection;
Keys << podzial.at(0);
Values << podzial.at(0);
}
line.clear();
}
}
void IniFile::Save( QString FileName )
{
QFile open( FileName );
open.open( QIODevice::WriteOnly | QIODevice::Text );
QTextStream ts(&open);
QString LastSection = Sections.at(0);
ts << ini("[") << ini(LastSection) << ini("]") << "\n";
for( int i = 0; i < Sections.size(); ++i )
{
if( Sections.at(i) != LastSection )
{
ts << ini("[") << ini(Sections.at(i)) << ini("]") << "\n";
}
else
{
ts << ini(Keys.at(i)) << ini("=") << ini(Values.at(i)) << ini("\n");
}
}
ts << ini("end");
open.close();
}
QString IniFile::GetValue( QString Section, QString Key )
{
QString Return;
for( int i = 0; i < Section.size(); ++i )
{
if( Sections.at(i) == Section && Keys.at(i) == Key ) Return = Values.at(i);
else continue;
}
if( Return.isEmpty() ) return EMPTY();
else return Return;
}
void IniFile::WriteValue( QString Section, QString Key, QString Value )
{
if( GetValue( Section, Key ) != EMPTY() ) // Jezeli istnieje
{
for( int i = 0; i < Sections.size(); ++i )
{
if( Sections.at(i) == Section && Keys.at(i) == Key )
{
Values.removeAt(i);
Values.insert( (i-1), Value );
}
}
}
else
{
QStringList newSections, newKeys, newValues;
QString LastSection = Sections.at(0);
int i = 0;
for( ; i < ( Sections.size()+1 ); ++i )
{
if( Sections.at(i) != Section )
{
newSections << Sections.at(i);
newKeys << Keys.at(i);
newValues << Values.at(i);
LastSection = Sections.at(i);
}
else
{
newSections << LastSection;
newKeys << Key;
newValues << Value;
++i;
}
++i;
}
Sections.clear();
Keys.clear();
Values.clear();
for( int j = 0; j < newSections.size(); ++j )
{
Sections << newSections.at(i);
Keys << newKeys.at(i);
Values << newValues.at(i);
}
}
}
QString IniFile::GetSectionsNames(QString separator)
{
return Sections.join( separator );
}
QString IniFile::GetKeysNames(QString Section, QString separator)
{
QString Return;
for( int i = 0; i < Sections.size(); ++i )
{
if( Sections.at(i) == Section )
Return += ( Keys.at(i) + separator );
}
return Return;
}
QString IniFile::EMPTY()
{
return QString("=EMPTY=");
}
Wiem że są tutaj niepotrzebne funkcje i wgl ale po prostu chce nauczyć sie używania klas. Mój problem polega na tym że kiedy wywołuje w projekcie
FNC::IniFile ini;
ini.Open("Ini.ini");
itd. To zawsze wyrzuca mi błędy:
'C:\Users...\manager.cpp:-1: błąd: undefined reference to
FNC::IniFile::IniFile()' 'C:\Users\...\manager.cpp:-1: błąd: undefined reference to
FNC::Open(QString)'
'C:\Users...\manager.cpp:-1: błąd: undefined reference toFNC::IniFile::GetSectionsNames(QString)' 'C:\Users\...\manager.cpp:-1: błąd: undefined reference to
FNC::GetValue(QString, QString)'
'C:\Users...\manager.cpp:-1: błąd: undefined reference toFNC::IniFile::GetValue(QString, QString)' ':-1: błąd: release/manager.o: bad reloc address 0x20 in section
.text$_ZN7QStringD1Ev[__ZN7QStringD1Ev]'
'collect2.exe:-1: błąd: error: ld returned 1 exit status'
I nie ważne w jakim środowisku piszę (Code::Blocks, Qt Creator) to zawsze wyrzuca mi te błędy. Nagłówki są dołączone, prubowałem z
extern "C" { /*...*/ }
ale też nie działa :c