Я пытаюсь разработать небольшое приложение для Windows, чтобы улучшить свои навыки C++ вне рамок MFC и помочь в изучении иностранных языков.
Я хотел бы создать небольшое, личное и простое приложение. -port_and_use словарь, и, хотя у меня нет проблем с разработкой графического интерфейса, у меня большие проблемы с сохранением и восстановлением данных.
Моя идея состоит в том, чтобы записать двоичные файлы со следующей структурой:
int (representing the number of words)
int (representing the string length + \0)
sequence of characters zero-terminated.
Теперь я я изучаю русский язык, а мой основной язык итальянский, поэтому я не могу использовать старый добрый std::string для записи слов, более того, спасибо Microsoft, я использую VS2010 со всеми благами и плохие файлы, которые идут с ним. Я показываю вам свои подпрограммы для записи int и wstring://Writing int
void CDizionario::ScriviInt( int nInt, wofstream& file ) const
{
file.write( reinterpret_cast < const wchar_t * > ( &nInt ), sizeof( nInt ) );
file.flush();
}
// Writing string
void CDizionario::ScriviWString( int nLStringa, const wstring* pStrStringa, wofstream& file ) const
{
wchar_t cTerminatore;
string strStringa;
file.write( pStrStringa->c_str(), nLStringa );
file.flush();
cTerminatore = L'\0';
file.write( &cTerminatore, sizeof( wchar_t ) );
file.flush();
}
// Reading int
void CDizionario::LeggiInt( int *pInt, wifstream& file )
{
file.read( reinterpret_cast < wchar_t * >( pInt ), sizeof( int ) );
}
// Reading wstring
void CDizionario::LeggiWString( int nLStringa, wstring& strStringa, wifstream& file )
{
wchar_t *pBuf;
streamsize byteDaLeggere;
byteDaLeggere = nLStringa;
pBuf = new wchar_t[(unsigned int)( byteDaLeggere * sizeof( wchar_t ) )];
file.read( pBuf, byteDaLeggere * sizeof( wchar_t ) );
strStringa.append( pBuf );
delete [] pBuf;
}
// Constructor
CDizionario::CDizionario( void )
{
m_pLoc = new locale( locale::classic(), new codecvt_utf8_utf16 );
}
// Somewhere in my code before calling LeggiInt/ScriviInt/LeggiWString/ScriviWString:
// ...
file.imbue( *m_pLoc );
Что ж, мой первый тест был: ciao - привет, результат:
01 00 ee bc 90 22 05 00 ee bc 90 22 63 69 61 6f
00 ec b3 8c 07 00 ee bc 90 22 d0 bf d1 80 d0 b8
d0 b2 d0 b5 d1 82 00 ec b3 8c
Числа читаются правильно, проблема возникает, когда я записываю строки: я ожидал, что ciao ( 63 69 61 6f 00 ec b3 8c) было записано в 10 байтах (размер wchar_t), а не в 5, как это бывает при переводе на русский язык ( d0 bf d1 80 d0 b8 d0 b2 d0 b5 d1 82 00 ec b3 8c).Явно что-то упускаю, но не могу понять что. Ребята, вы можете мне помочь? Кроме того, если вы знаете лучший подход к решению проблемы, я не предубежден.
РЕДАКТИРОВАТЬ: РЕШЕНИЕ
Следуя первому из двух методов, представленных @JamesKanze, я решил пожертвовать некоторой переносимостью и позволить системе сделать мою домашнюю работу: void CDizionario::LeggiInt( int *pInt, ifstream& file )
{
file.read( reinterpret_cast( pInt ), sizeof( int ) );
}
void CDizionario::LeggiWString( int nLStringa, wstring& strStringa, ifstream& file ) { char *pBuf; streamsize byteDaLeggere; wstring_convert> converter; byteDaLeggere = nLStringa; pBuf = new char[byteDaLeggere]; file.read( pBuf, byteDaLeggere ); strStringa = converter.from_bytes( pBuf ); delete [] pBuf; }
void CDizionario::ScriviInt( int nInt, ofstream& file ) const { file.write( reinterpret_cast( &nInt ), sizeof( nInt ) ); file.flush(); } void CDizionario::ScriviWString( const wstring* pStrStringa, ofstream& file ) const { char cTerminatore; string strStringa; wstring_convert> converter; strStringa = converter.to_bytes( pStrStringa->c_str() ); ScriviInt( strStringa.length() + 1, file ); file.write( strStringa.c_str(), strStringa.length() ); file.flush(); cTerminatore = '\0'; file.write( &cTerminatore, sizeof( char ) ); file.flush(); }