こんにちは。
先日半角から全角の変換について質問をさせていただきました。
変換自体は無事にできたのですが
次のステップがうまくいかないので質問いたします。
やりたいことはファイルを読みこんで半角を全角へ変換です。
while(( fgets( chstr,6,fp )) != NULL ){
今は上記のようにファイルから6文字づつ読みこんでいます。
しかしこれだと、半角全角混合のファイルを読むと
ところどころ誤変換になってしまいます。
そこで1文字づつ読みこみをしたいと思っているのですが
どうすればいいのでしょう。
できればchar型で受け取りたいのですが。
または他に何かいい方法がありますでしょうか?
よろしくお願いします。
>やりたいことはファイルを読みこんで半角を全角へ変換です。
このファイルの文字コードは何でしょうか?
>このファイルの文字コードは何でしょうか?
も、文字コード?
えっとVC++のヘルプで「文字コード」を検索したら
ASCⅡとでたのですが、これでいいのでしょうか?
>ASCⅡとでたのですが、これでいいのでしょうか?
ということは、変換前のファイルには半角文字のみが書かれていると考えていいということでし
ょうか?
>しかしこれだと、半角全角混合のファイルを読むと
>ところどころ誤変換になってしまいます。
すみません。
よく読んでいなかったようです。
>そこで1文字づつ読みこみをしたいと思っているのですが
1Byteではなく、半角・全角のどちらでも常に1文字づつということですか?
はい、そうです。
今までは適当な文字数分を
例えば char chstr[64] に格納して
_mbsncpy( mbb_str, pstr, 1);
で1文字を別のmbb_strに格納していたのですが
この時点でもうすでに文字化けをしているようなので
ファイルの読込から1文字づつ読込たいと思いました。
>ファイルの読込から1文字づつ読込たいと思いました。
しかしながら、読み込んでからでないと半角・全角の区別ができませんし。
とりあえず、1度に読み込むバイト数は適当でいいと思います。
で、誤変換を防ぐには全角文字の場合に変換をしてはいけませんよね。
結局、1Byteずつ半角・全角の先行バイト・全角の後続バイトを判定し、
半角なら全角へ変換という流れになるでしょうか。
判定は _mbbtype を使用するのがいいのではないかと思います。
いえ、変換をしたときに誤変換をしているのではないようです。
_mbsncpy( mbb_str, pstr, 1);
で1文字ずつ読みこんだ時点で
1度ディスプレイに表示して確認をしているのですが
この時点で誤変換が起きているのです。
例)
[読込]
tEsカサ ギ17;6[R50@eARIGat
[結果]
tEsカサ ギ1V;6[q50@eARIGat
↑
済みません、間違えました。
tEsカサ ギ1V;6[q50@eARIGat
Vとqの部分が違いますよね。
本来ならば読みこんだものが、そのまま表示されるはずなのですが。
>_mbsncpy( mbb_str, pstr, 1);
>tEsカサ ギ17;6[R50@eARIGat
こちらの環境(NT4.0 SP6a VC6.0++ SP3)で少し試してみました。
_mbsncpy が少し変?な動きをみせました。
1文字ずつコピーしてみましたが、
mbb_str
1:t
2:tE
3:tEs
4:tEsカ
5:tEsカ
6:tEsカサ
7:tEsカサ 変化なし
8:tEsカサ
9:tEsカサ ギ
10:tEsカサ ギ 変化なし
11:tEsカサ ギ17
・
・
・
という具合です。
全角文字をコピーした後は1回休み?みたいな感じがしました。
すみません。
テストの仕方がまずかったようです。
どうもバッファの先頭が全角文字の後続バイトからになった時そのような状態になるようです
ね。
while ( *pstr ) {
_mbsncpy( mbb_str, pstr, 1);
・
・ 変換処理
・
pstr = _mbsinc( pstr );
}
最後の行で文字列へのポインタを1つ進めているのですが
これでもコピーはしてくれないのでしょうか?
>pstr = _mbsinc( pstr );
自体は問題ないようですが
> while(( fgets( chstr,6,fp )) != NULL ){
この部分と合わさった場合にどうなっているのでしょう?
こちらでも一応簡単な変換を除いたコードを書いてみました。
int main(int argc, char** argv)
{
if(argc < 3)
{
return 2;
}
FILE* rfp = fopen(argv[1], r);
FILE* wfp = fopen(argv[2], w);
int nType = 0;
int ch;
TCHAR szTemp[3];
if(rfp)
{
while((ch = fgetc(rfp)) != EOF)
{
if((nType = _mbbtype(ch, nType)) == _MBC_SINGLE)
{
// ToDo: 変換 例:ア → ア
fprintf(wfp, %s, szTemp);
}
else
{
fprintf(wfp, %c, ch);
}
}
fclose(rfp);
fclose(wfp);
}
return 0;
}
int main(int argc, char* argv[])
{
char fname[68];
char chstr[12];
unsigned char *pstr;
unsigned char mbb_str[3];
int intstr;
while(( fgets( chstr,6,fp )) != NULL ){
pstr = (unsigned char *)chstr;
while ( *pstr ) {
memset( mbb_str, 0, sizeof( mbb_str ));
_mbsncpy( mbb_str, pstr, 1);
intstr = AlphaChange((char *)pstr);//変換処理
if( intstr == 0){
printf(%s,mbb_str);
}
pstr = _mbsinc( pstr );
}
}
}
int AlphaChange(char *str)
{
int i;
char chStr[3];
memset(chStr,0x00,sizeof(chStr));
strncpy(chStr,str,1);
chStr[1] = '\0';
//printf(%s,chStr);
for(i=0;i<sizeof(AlphaTable)/sizeof(Alpha_Table);i++){
while(pchMoji=strstr(chStr,AlphaTable[i].han)){
pchMoji[0]=AlphaTable[i].zen[0];
pchMoji[1]=AlphaTable[i].zen[1];
printf(%s,pchMoji);
return( 1 );
}
}
return( 0 );
}
struct Alpha_Table{
char han[3]; /* 半角 */
char zen[3]; /* 全角 */
}AlphaTable[]={
A,A,B,B,C,C,D,D,E,E,
F,F,G,G,H,H,I,I,J,J, ...
変換処理ではテーブルを使って変換させています。
読みこんだ文字が全角ならそのまま出力させています。