Działający przykład (przynajmniej na Windowsie).
#include <stdio.h>
#include <string.h>
int get_char_bytes( unsigned char val )
{
if( val < 128 ) return 1;
else if( val < 224 ) return 2;
else if( val < 240 ) return 3;
return 4;
}
void _add_utf8_to_ansi_string( char * val, char * string, size_t * counter, size_t limit )
{
size_t length = strlen( val ), x = 0;
if( * counter + length > limit )
return;
while( x < length )
string[( * counter ) ++ ] = val[ x++ ];
}
void add_utf8_to_ansi_string( int val, char * string, size_t * counter, size_t limit )
{
if( * counter + 1 > limit )
return;
if( val <= 0x7F )
string[( * counter ) ++ ] =( char ) val;
else switch( val )
{
case 0xC484: _add_utf8_to_ansi_string( "Ą", string, counter, limit ); break;
case 0xC485: _add_utf8_to_ansi_string( "ą", string, counter, limit ); break;
case 0xC486: _add_utf8_to_ansi_string( "Ć", string, counter, limit ); break;
case 0xC487: _add_utf8_to_ansi_string( "ć", string, counter, limit ); break;
case 0xC498: _add_utf8_to_ansi_string( "Ę", string, counter, limit ); break;
case 0xC499: _add_utf8_to_ansi_string( "ę", string, counter, limit ); break;
case 0xC581: _add_utf8_to_ansi_string( "Ł", string, counter, limit ); break;
case 0xC582: _add_utf8_to_ansi_string( "ł", string, counter, limit ); break;
case 0xC393: _add_utf8_to_ansi_string( "Ó", string, counter, limit ); break;
case 0xC3B3: _add_utf8_to_ansi_string( "ó", string, counter, limit ); break;
case 0xC59A: _add_utf8_to_ansi_string( "Ś", string, counter, limit ); break;
case 0xC59B: _add_utf8_to_ansi_string( "ś", string, counter, limit ); break;
case 0xC5BB: _add_utf8_to_ansi_string( "Ż", string, counter, limit ); break;
case 0xC5BC: _add_utf8_to_ansi_string( "ż", string, counter, limit ); break;
case 0xC5B9: _add_utf8_to_ansi_string( "Ź", string, counter, limit ); break;
case 0xC5BA: _add_utf8_to_ansi_string( "ź", string, counter, limit ); break;
case 0xC583: _add_utf8_to_ansi_string( "Ń", string, counter, limit ); break;
case 0xC584: _add_utf8_to_ansi_string( "ń", string, counter, limit ); break;
}
}
int main( int argc, char ** argv )
{
FILE * data = NULL;
int sign = 0;
size_t x = 0, y = 0;
char nfname[ 256 ] = { 0 };
int resnum = 0;
data = fopen( "data.txt", "r" );
if( !data ) return 1;
while(( sign = fgetc( data ) ) != EOF && x < 255 )
{
resnum = 0;
y = get_char_bytes(( unsigned char ) sign );
while( --y > 0 )
{
resnum |= sign << 8 * y;
printf( "%d ", sign );
sign = fgetc( data );
}
printf( "%d ", sign );
resnum |= sign;
printf( "%d (0x%X)\n", resnum, resnum );
add_utf8_to_ansi_string( resnum, nfname, & x, 256 );
}
printf( "%s\n", nfname );
data = fopen( "test.txt", "w" );
if( !data ) return 1;
fclose( data );
rename( "test.txt", nfname );
getchar();
return 0;
}
Sprawdź czy działa. Kod działa dla UTF-8. Ale jedno ale. Plik źródłowy który kompilujesz musi być (przynajmniej na VisualStudio) zapisany w kodowaniu cp1250 lub UTF-8 (cp65001) z sygnaturą (czyli z BOM) - kodowanie możesz zmienić w programie Notepad i skompilować gcc (program napisany jest w C - nie nawidzę C++ i staram się go omijać szerokim łukiem).
Nie wiem również jak program zachowa się pod linuksem. Musisz to sprawdzić.
PS: Oczywiście plik data.txt musisz mieć utworzony. Kodowanie UTF-8, zawartość np. taka: