Last active
December 22, 2015 02:38
-
-
Save brokendish/6404612 to your computer and use it in GitHub Desktop.
文字コード変換を行う
1文字ずつ文字コード変換を行う。変換不可文字があった場合は「?」に置き換える
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <iconv.h> | |
#include <locale.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <wchar.h> | |
/* fgetsの指定バイト数 */ | |
#define READ_SIZE 4096 | |
/* 置き換え文字のサイズ */ | |
#define CONTENT_SIZE 10 | |
/*ダメ文字置き換え文字*/ | |
#define DAMEMOJI "?" | |
char outbuf[CONTENT_SIZE]; | |
int convert(char const *src, | |
char const *dest, | |
char const *text, | |
char *buf, | |
size_t bufsize); | |
void chr_conv(char const *str,char *hairtetu[],int cnt); | |
/* | |
--------------------------------------------------------------- | |
文字コード変換を行う | |
1文字ずつ文字コード変換を行う。変換不可文字があった場合は「?」に置き換える | |
【引数】 | |
1:utf8-->cp932 | |
2:cp932-->utf8 | |
ex)入力文字列をUTF8からcp932に変換して表示 | |
echo "変換文字"|./iconv_Chk 1 | |
ex)入力ファイルをUTF8からcp932に変換して表示 | |
cat aaa.txt|./iconv_Chk 1 | |
【コンパイル】 | |
gcc -o iconv_Chk iconv_Chk.c | |
【UTF8ロケールで実行】 | |
export LANG=ja_JP.utf8 && echo "日本語表示だよこれ〠と、この3つ㊽㊾㊿はcp932では表示出来ないよ!"|./iconv_Chk 1 | |
実行&確認(結果をUFT8に変換して表示) | |
export LANG=ja_JP.utf8 && echo "日本語表示だよこれ〠と、この3つ㊽㊾㊿はcp932では表示出来ないよ!"|./iconv_Chk 1|iconv -f cp932 -t utf8 | |
【SJISロケールで実行】 | |
export LANG=ja_JP.sjis && echo "日本語表示だよこれ〜と、この3つ|=¥はcp932でも表示出来る!"|./iconv_Chk 2 | |
【コンパイル&実行】 | |
gcc -o iconv_Chk iconv_Chk.c && export LANG=ja_JP.utf8 && echo "日本語表示aああbいcうdえ"|./iconv_Chk 1 | |
------テストケース-------------- | |
①UTF8→cp932変換 | |
・データ[test_utf8.txt] | |
「日本語表示だよこれ〠と、この3つ㊽㊾㊿はcp932では表示出来ないよ!」 | |
を文字コードUTF8で作成 | |
・UTF8環境で実行 | |
UTF8→cp932変換 結果をiconvにパイプして変換不可文字「〠㊽㊾㊿」が「?」に変換されていること | |
・環境設定 | |
export LANG=ja_JP.utf8 | |
・実行 | |
cat test_utf8.txt|./iconv_Chk 1|iconv -f cp932 -t utf8 | |
・SJIS環境で実行 | |
UTF8→cp932変換 結果をiconvにパイプして変換不可文字「〠㊽㊾㊿」が「?」に変換されていること | |
・環境設定 | |
export LANG=ja_JP.sjis | |
・実行 | |
cat test_utf8.txt|./iconv_Chk 1|iconv -f cp932 -t utf8 | |
②cp932→UTF8変換 | |
・データ[test_sjis.txt] | |
「日本語表示だよこれ〜と、この3つ|=¥はcp932でも表示出来る!」 | |
を文字コードcp932で作成 | |
・UTF8環境で実行 | |
cp932→UTF8変換 全て変換されていること | |
・環境設定 | |
export LANG=ja_JP.utf8 | |
・実行 | |
cat test_sjis.txt|./iconv_Chk 2 | |
・SJIS環境で実行 | |
cp932→UTF8変換 変換 全て変換されていること | |
・環境設定 | |
export LANG=ja_JP.sjis | |
・実行 | |
cat test_sjis.txt|./iconv_Chk 2 | |
テスト実行 | |
echo "-------------------------------------------------------------" | |
export LANG=ja_JP.utf8 | |
cat test_utf8.txt|./iconv_Chk 1|iconv -f cp932 -t utf8 | |
echo "-------------------------------------------------------------" | |
export LANG=ja_JP.sjis | |
cat test_utf8.txt|./iconv_Chk 1|iconv -f cp932 -t utf8 | |
echo "-------------------------------------------------------------" | |
export LANG=ja_JP.utf8 | |
cat test_sjis.txt|./iconv_Chk 2 | |
echo "-------------------------------------------------------------" | |
export LANG=ja_JP.sjis | |
cat test_sjis.txt|./iconv_Chk 2 | |
export LANG=ja_JP.utf8 | |
--------------------------------------------------------------- | |
*/ | |
main(int argc, char **argv) | |
{ | |
int ret; | |
char *moji; | |
char *moji_to; | |
/*ロケールの設定*/ | |
char *loc; | |
//loc = setlocale( LC_ALL, "ja_JP.sjis" ); | |
loc = setlocale( LC_ALL, "" ); /*システムのlocale設定を使用する*/ | |
printf("LOCALE====%s\n",loc); | |
/*引数の判定*/ | |
int proc = atoi(argv[1]); | |
//1:utf8-->cp932 | |
//2:cp932-->utf8 | |
char *ifrom=""; | |
char *ito=""; | |
switch(proc){ | |
case 1: | |
loc = setlocale( LC_ALL, "ja_JP.utf8" ); /*ロケールをUTF8に変更*/ | |
ifrom="UTF-8"; | |
ito="cp932"; | |
break; | |
case 2: | |
loc = setlocale( LC_ALL, "ja_JP.sjis" ); /*ロケールをSJISに変更*/ | |
ifrom="cp932"; | |
ito="UTF-8"; | |
break; | |
default: | |
break; | |
} | |
/* 標準入力からデータを取得(パイプ)-----------------------------------S | |
*/ | |
char *buf; | |
char *buf2; | |
int r=2; | |
int inMojiSize=0; | |
buf = (char *)calloc(READ_SIZE,sizeof(char)); | |
buf2 = (char *)calloc(READ_SIZE,sizeof(char)); | |
while (fgets(buf,READ_SIZE,stdin) != NULL){ | |
/* 容量が足りなくなったら再確保 */ | |
buf2 = (char *)realloc(buf2,READ_SIZE * r ); | |
/* 1行又は指定バイト単位で読み込んだデータを蓄積 */ | |
strcat(buf2,buf); | |
r++; | |
} | |
moji = buf2; | |
/*入力のサイズ取得*/ | |
inMojiSize = strlen(moji); | |
/* 標準入力からデータを取得(パイプ)-----------------------------------E | |
*/ | |
int i; | |
int cnt; | |
char *remoji[inMojiSize]; | |
char *retstr[inMojiSize]; | |
/*1文字ずつ配列に格納する*/ | |
chr_conv(moji,remoji,inMojiSize); | |
puts("***************************"); | |
for(cnt=0;remoji[cnt]!='\0';cnt++){ | |
#ifdef DEBUG1 | |
printf("--変換前[%02s] cnt:%d ",remoji[cnt],cnt); | |
#endif | |
/*UTF8->cp932に変換(1文字ずつ)*/ | |
ret = convert(ifrom, ito, | |
remoji[cnt], | |
outbuf, sizeof(outbuf)); | |
if (ret) { | |
#ifdef DEBUG1 | |
printf("変換後[%02s] \n", outbuf); | |
#endif | |
} | |
else { | |
/*変換不能文字があった場合「!NG!」に変換*/ | |
strcpy(outbuf,DAMEMOJI); | |
#ifdef DEBUG1 | |
printf("変換後[%02s] \n", outbuf); | |
#endif | |
} | |
/*1文字ずつをつなぎ合わせる*/ | |
strcat((char *)retstr,outbuf); | |
} | |
puts((char *)retstr); | |
#ifdef DEBUG1 | |
printf("1文字変換後>---len--:%d [%s]\n",strlen(retstr),retstr); | |
puts("\n----------------1文字convert-------------------E"); | |
#endif | |
puts("***************************"); | |
free(buf); | |
free(buf2); | |
} | |
/* | |
--------------------------------------------------------------- | |
引数で渡された文字列「char const *str」を | |
1文字ずつにして配列「char *hairtetu[]」に格納して返却する | |
--------------------------------------------------------------- | |
*/ | |
void chr_conv(char const *str,char *hairtetu[],int cnt){ | |
int i=0; | |
int j,len; | |
int h=0; | |
char *rep; | |
rep = (char *)malloc(sizeof(char) * cnt ); | |
while(str[i]!='\0'){ | |
/*マルチバイト文字のバイト数を取得(1文字)*/ | |
len= mblen( &str[i], MB_CUR_MAX ); | |
/*ワークをクリア*/ | |
for(j=0;j<cnt;j++){ | |
rep[j]='\0'; | |
} | |
/*文字数を指定してコピー*/ | |
strncpy(rep,str+i,len); | |
if(len == 1){ | |
/*シングルバイト文字*/ | |
} | |
else{ | |
/*マルチバイト文字*/ | |
} | |
/*配列要素を確保して1文字入れる*/ | |
hairtetu[h]=malloc(sizeof(rep)); | |
strcpy(hairtetu[h],rep); | |
h++; | |
i+=len; | |
} | |
/*最終位置の設定*/ | |
hairtetu[h]=malloc(sizeof(rep)); | |
hairtetu[h]='\0'; | |
free(rep); | |
} | |
/* | |
--------------------------------------------------------------- | |
文字コード変換処理。iconvを利用 | |
--------------------------------------------------------------- | |
*/ | |
int convert(char const *src, | |
char const *dest, | |
char const *intext, | |
char *outbuf, | |
size_t bufsize) | |
{ | |
iconv_t cd; | |
size_t insrclen, outsrclen; | |
size_t ret; | |
cd = iconv_open(dest, src); | |
if (cd == (iconv_t)-1) { | |
#ifdef DEBUG1 | |
perror("iconv open"); | |
#endif | |
return 0; | |
} | |
insrclen = strlen(intext); | |
outsrclen = bufsize - 1; | |
memset(outbuf, '\0', bufsize); | |
ret = iconv(cd, &intext, &insrclen, &outbuf, &outsrclen); | |
if (ret == -1) { | |
#ifdef DEBUG1 | |
perror("iconv"); | |
#endif | |
return 0; | |
} | |
iconv_close(cd); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment