- 締切済み
C言語のプログラミングで文字コードを表示する方法を教えてください。
ファイル名<sample-utf8.txt> 32 30 30 38 e5 b9 b4 35 e6 9c 88 32 37 e6 97 a5 0d 0a ef bc 92 ef bc 90 ef bc 90 ef bc 98 e5 b9 b4 ef bc 95 e6 9c 88 ef bc 92 ef bc 97 e6 97 a5 0d 0a e8 a8 88 e7 ae 97 e6 a9 9f e3 82 b7 e3 82 b9 e3 83 86 e3 83 a0 ef bc 91 テキストメモの文字を表示するプログラムをC言語で作りたいのですがわかりません。どなたかソースコードを教えていただけると助かります。よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- yama5140
- ベストアンサー率54% (136/250)
>どなたかソースコードを教えていただけると助かります。 年寄りが、頭の体操を兼ねて作ってみました(BorlandC++5.5.1, win2k)。 ずいぶんとダダラとなってしまい・・。 ・sample-utf8.txt を見ると、3バイトコード文字がレコード(行)を跨いでいるのですね・・。 これにより、ソースが若干複雑になっています。→ 改行までを配列に格納 → 処理 処理:utf8 → unicode → sjis という複雑なことやっています。 複雑な理由:下の表を見つけたもんで・・。 http://homepage3.nifty.com/aokura/src/cp932.html ★ #include <stdio.h> #define un_shrt unsigned short char cHexa[ 32 ] = "0123456789abcdef"; typedef struct{ un_shrt unicode; un_shrt sjiscode; }CONVTABLE; const CONVTABLE conv_table[ 16 ] = { { 0x30B7, 0x8356 }, { 0x30B9, 0x8358 }, { 0x30C6, 0x8365 }, { 0x30E0, 0x8380 }, { 0x5E74, 0x944E }, { 0x6A5F, 0x8B40 }, { 0x65E5, 0x93FA }, { 0x6708, 0x8C8E }, { 0x7B97, 0x8E5A }, { 0x8A08, 0x8C76 }, { 0xFF10, 0x824F }, { 0xFF11, 0x8250 }, { 0xFF12, 0x8251 }, { 0xFF15, 0x8254 }, { 0xFF17, 0x8256 }, { 0xFF18, 0x8257 } }; int Unicode2SJIS( int iVal ) { int i; for( i = 0; i < 16; i++ ){ if( (un_shrt)iVal == conv_table[ i ].unicode ) return( (int)conv_table[ i ].sjiscode ); } fprintf( stderr, "★より補充してください { 0x%04X, 0xxxxx },\n", iVal ); return( 0x81A0 ); } int toDecimal( char a ) { int i; for( i = 0; i < 16; i++ ){ if( a == cHexa[ i ] ) return( i ); } return( 0 ); } int toUnicodeA( char aaaa, char bb0, char bb1 ) { int iVal; iVal = toDecimal( aaaa ) << 4; iVal += ( ( 0x03 & toDecimal( bb0 ) ) << 2 ); iVal += ( toDecimal( bb1 ) >> 2 ); return( iVal ); } int toUnicodeB( char cc0, char cc1, char dddd ) { int iVal = 0; iVal += ( ( 0x03 & toDecimal( cc0 ) ) << 6 ); iVal += ( ( 0x03 & toDecimal( cc1 ) ) << 4 ); iVal += toDecimal( dddd ); return( iVal ); } void Henkan( char cWork[], char cStr[], int nn ) { int i, k = 0; int iUni, iSjs; for( i = 0; i < nn; i += 3 ){ if( '3' == cWork[ i ] ){ // ASCIIコード 数字 cStr[ k++ ] = cWork[ i + 1 ]; cStr[ k ] = '\0'; continue; } iUni = toUnicodeA( cWork[ i + 1 ], cWork[ i + 3 ], cWork[ i + 4 ] ) << 8; iUni+= toUnicodeB( cWork[ i + 4 ], cWork[ i + 6 ], cWork[ i + 7 ] ); iSjs = Unicode2SJIS( iUni ); cStr[ k++ ] = (char)( iSjs >> 8 ); cStr[ k++ ] = (char)( ( iSjs << 8 ) >> 8 ); cStr[ k ] = '\0'; i += 6; // 3バイトコード調整 } } int main() { int i, nn = 0; char cBuf[ 256 ], cWork[ 2048 ], cStr[ 1024 ]; FILE *fp; fp = fopen( "sample-utf8.txt", "r" ); if( NULL == fp ) return( -1 ); while( NULL != fgets( cBuf, 256, fp ) ){ if( nn ){ cWork[ nn++ ] = ' '; cWork[ nn ] = '\0'; } for( i = 0; i < 256; i++ ){ if( cBuf[ i ] < ' ' ) break; // 行末 if( ( '0' == cBuf[ i ] ) && ( 'd' == cBuf[ i + 1 ] ) ){ // 改行 Henkan( cWork, cStr, nn ); printf( "%s\n", cStr ); nn = 0; i += 5; // 0a skip continue; } cWork[ nn++ ] = cBuf[ i ]; cWork[ nn ] = '\0'; } } fclose( fp ); if( nn ){ Henkan( cWork, cStr, nn ); printf( "%s\n", cStr ); } return( 0 ); } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
- salsberry
- ベストアンサー率69% (495/711)
sample-utf8.txtというファイルに"32 30 … 91"と書かれていて、その内容を「UTF8の文字列の文字コードを16進表記したもの」とみなして、元のUTF8の文字列の内容を表示したいということでいいですか? C言語では文字コードの扱いはプラットフォームによって異なるので、対象のOSやコンパイラを明らかにしてください。 たとえば、UTF8に対応している端末ならば下記のプログラムだけでもほぼ目的を達することができてしまいます (sample-utf8.txtの内容は標準入力から読み込む想定)。 #include <stdio.h> int main() { char c; while (scanf("%hhx", &c) > 0) { putchar(c); } return 0; } ところで、なぜ2008年?