電子書籍の厳選無料作品が豊富!

ファイル名<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言語で作りたいのですがわかりません。どなたかソースコードを教えていただけると助かります。よろしくお願いします。

A 回答 (2件)

>どなたかソースコードを教えていただけると助かります。



 年寄りが、頭の体操を兼ねて作ってみました(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 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
    • good
    • 0

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年?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!