ファイルの読み込み

[戻る]
makoto 2002/02/12(火) 12:41:05
こんにちは。

先日半角から全角の変換について質問をさせていただきました。
変換自体は無事にできたのですが
次のステップがうまくいかないので質問いたします。

やりたいことはファイルを読みこんで半角を全角へ変換です。
    while(( fgets( chstr,6,fp )) != NULL ){  
今は上記のようにファイルから6文字づつ読みこんでいます。
しかしこれだと、半角全角混合のファイルを読むと
ところどころ誤変換になってしまいます。

そこで1文字づつ読みこみをしたいと思っているのですが
どうすればいいのでしょう。
できればchar型で受け取りたいのですが。

または他に何かいい方法がありますでしょうか?
よろしくお願いします。

NGA 2002/02/12(火) 12:45:25
>やりたいことはファイルを読みこんで半角を全角へ変換です。

このファイルの文字コードは何でしょうか?

makoto 2002/02/12(火) 12:55:07
>このファイルの文字コードは何でしょうか?

も、文字コード?
えっとVC++のヘルプで「文字コード」を検索したら
ASCUとでたのですが、これでいいのでしょうか?

NGA 2002/02/12(火) 13:00:53
>ASCUとでたのですが、これでいいのでしょうか?

ということは、変換前のファイルには半角文字のみが書かれていると考えていいということでし
ょうか?

NGA 2002/02/12(火) 13:03:13
>しかしこれだと、半角全角混合のファイルを読むと
>ところどころ誤変換になってしまいます。

すみません。
よく読んでいなかったようです。

NGA 2002/02/12(火) 13:13:57
>そこで1文字づつ読みこみをしたいと思っているのですが

1Byteではなく、半角・全角のどちらでも常に1文字づつということですか?

makoto 2002/02/12(火) 13:23:30
はい、そうです。

今までは適当な文字数分を
例えば    char chstr[64] に格納して
_mbsncpy( mbb_str, pstr, 1);
で1文字を別のmbb_strに格納していたのですが
この時点でもうすでに文字化けをしているようなので

ファイルの読込から1文字づつ読込たいと思いました。

NGA 2002/02/12(火) 13:29:35
>ファイルの読込から1文字づつ読込たいと思いました。

しかしながら、読み込んでからでないと半角・全角の区別ができませんし。

とりあえず、1度に読み込むバイト数は適当でいいと思います。
で、誤変換を防ぐには全角文字の場合に変換をしてはいけませんよね。
結局、1Byteずつ半角・全角の先行バイト・全角の後続バイトを判定し、
半角なら全角へ変換という流れになるでしょうか。

判定は _mbbtype を使用するのがいいのではないかと思います。

makoto 2002/02/12(火) 13:42:15
いえ、変換をしたときに誤変換をしているのではないようです。

_mbsncpy( mbb_str, pstr, 1);
で1文字ずつ読みこんだ時点で
1度ディスプレイに表示して確認をしているのですが
この時点で誤変換が起きているのです。

例)
[読込]
tEsカサ ギ17;6[R50@eARIGat

[結果]
tEsカサ ギ1V;6[q50@eARIGat
    ↑

makoto 2002/02/12(火) 13:44:03
済みません、間違えました。

tEsカサ ギ1V;6[q50@eARIGat

Vとqの部分が違いますよね。
本来ならば読みこんだものが、そのまま表示されるはずなのですが。
    

NGA 2002/02/12(火) 14:08:38
>_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回休み?みたいな感じがしました。

NGA 2002/02/12(火) 14:15:07
すみません。
テストの仕方がまずかったようです。
どうもバッファの先頭が全角文字の後続バイトからになった時そのような状態になるようです
ね。

makoto 2002/02/12(火) 14:24:12
while ( *pstr ) {
  _mbsncpy( mbb_str, pstr, 1);
     ・
     ・ 変換処理
     ・
  pstr = _mbsinc( pstr );
}
最後の行で文字列へのポインタを1つ進めているのですが
これでもコピーはしてくれないのでしょうか?

NGA 2002/02/12(火) 14:34:16
>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;
}

makoto 2002/02/12(火) 14:49:58
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", ...


変換処理ではテーブルを使って変換させています。
読みこんだ文字が全角ならそのまま出力させています。

NGA 2002/02/12(火) 15:10:39
int main(int argc, char** argv)
{
    char fname[68]; 
    char chstr[12];
    unsigned char *pstr;
    unsigned char mbb_str[3];
    int intstr;
    FILE* fp;

    if(argc < 2 || !(fp = fopen(argv[1], "r")))
    {
        return 2;
    }

    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 );
        }
    }

    fclose(fp);

    return 0;
}

以上のコードで試すと、
読込ファイル : "tEsカサ ギ17;6[R50@eARIGat"
出力結果     : "tEsカサ ギ17;6[R50@eARIGat"
となりましたね。

makoto 2002/02/12(火) 15:25:57
NGAさんのように
変換をしないでそのまま表示させているのですが
やはり tEsカサ ギ1V;6[q50@eARIGat
のように「V」「q」がでてきてしまいます。

NGAさんのプログラムをそのまま使って
やってみたのですが
それでも同じ結果になってしまいました。
    

makoto 2002/02/12(火) 15:43:57
追加で。

while(( fgets( chstr,6,fp )) != NULL ){  
で、うまくいったと思っても
読み込み文字数を変えるとまた違った結果になったりします。

NGA 2002/02/12(火) 15:45:36
文字コード(JIS・S-JIS・EUC・UNICODE)を変えたり、Win98上で動かしてみたりしましたが、
どうしても "tEsカサ ギ1V;6[q50@eARIGat" を出すことができませんでした。

TAKA 2002/02/12(火) 16:04:02
> makotoさんへ

気になったのでよこからですが、
今のメインのみをもう一度省かず、コピーペーストしてくれませんか?
後、テキストファイルだと思われますが、もう一度作成しなおし、ためしても
だめですか?
バイナリ−EDITもっているなら、"tEsカサ ギ17;6[R50@eARIGat"
のダンプ等があるとわかりやすいです。

makoto 2002/02/12(火) 16:18:56
int main(int argc, char* argv[])
{
    char fname[68];
    char chstr[12];
    unsigned char *pstr;
    unsigned char mbb_str[3];

    FILE *fp;

    if (argc == 1) {
        printf("ファイル名を入力してください!\n");
        printf("ファイル名=");
        scanf("%s", fname);
    }else{
        strcpy(fname, argv[1]);
    }
   
    /* ファイルオープン */
    fp = fopen(fname, "r");
    if ( fp == NULL ) {
        printf("ファイルオープンに失敗しました");
        exit (1);
    }

    memset( chstr, 0, sizeof(chstr) );
         while(( fgets( chstr, 6, fp )) != NULL ){  
        pstr = (unsigned char *)chstr;

        while ( *pstr ) {
            memset( mbb_str, 0, sizeof( mbb_str ));
            //strncpy( (char *)mbb_str, (char *)pstr,1);
            _mbsncpy( mbb_str, pstr, 1);
    
                           printf("%s",mbb_str);
                        
            pstr = _mbsinc( pstr );    
        }
        memset( chstr, 0, sizeof(chstr) );
    }

    fclose(fp);
    return 0;
}

メインはこれです。
テキストファイルは作りなおしてみましたが
やはり結果は同じでした。

なにか原因があるのでしょうか?

NGA 2002/02/12(火) 16:29:07
う〜む、でませんねぇ。
makotoさんの方法で注意しなければいけない点は、ファイルから読み込んだ時に
全角文字が先行バイトと後続バイトに分断された場合のみくらいかと考えていましたが。

TAKA 2002/02/12(火) 16:48:50
> makotoさんの方法で注意しなければいけない点は、ファイルから読み込んだ時に
> 全角文字が先行バイトと後続バイトに分断された場合のみくらいかと考えていましたが。

私もそう思いメインを出してもらったのですが出ませんでした。

>   while(( fgets( chstr, 6, fp )) != NULL ){  
>        pstr = (unsigned char *)chstr;
>
>        while ( *pstr ) {
>            memset( mbb_str, 0, sizeof( mbb_str ));
>            //strncpy( (char *)mbb_str, (char *)pstr,1);
>            _mbsncpy( mbb_str, pstr, 1);
>    
>                           printf("%s",mbb_str);
>                        
>            pstr = _mbsinc( pstr );    
>        }
>        memset( chstr, 0, sizeof(chstr) );
>    }

ためしですが、下記の2パターンにこの部分を変えてみてください

パターン1:
   while(( fgets( chstr, 6, fp )) != NULL ){  
        pstr = (unsigned char *)chstr;
        printf("%s",pstr);
        memset( chstr, 0, sizeof(chstr) );
   }

パターン2:
   char wk[3];
   while(( fgets( chstr, 6, fp )) != NULL ){  
        pstr = (unsigned char *)chstr;

        memset( wk, 0x00, sizeof( wk ));
        while ( *pstr ) {
            memset( mbb_str, 0, sizeof( mbb_str ));
            //strncpy( (char *)mbb_str, (char *)pstr,1);
            _mbsncpy( mbb_str, pstr, 1);

            if (wk[0] != 0x00) {
                wk[1] = mbb_str;
                printf("%s",wk);
                memset( wk, 0, sizeof( wk ));
            }
            else if ((mbb_str & 0x80) == 0x80) {
                wk[0] = mbb_str;
            }
            else {
                printf("%s",mbb_str);
            } 
                        
            pstr = _mbsinc( pstr );    
        }
        memset( chstr, 0, sizeof(chstr) );
    }

TAKA 2002/02/12(火) 17:03:10
すみませんパターン2ですが、
mbb_str -> mbb_str[0]
としてください。
多分動かないとおもうのですが・・・。

makoto 2002/02/12(火) 17:06:41
パターン2の
else if ((mbb_str & 0x80) == 0x80) {
で以下のようなエラーが出ました。
        
error C2296: '&' : 不正な左オペランドです。

NGA 2002/02/12(火) 17:10:29
>パターン2の
>else if ((mbb_str & 0x80) == 0x80) {
>で以下のようなエラーが出ました。
>       
>error C2296: '&' : 不正な左オペランドです。

これもTAKAさんが一つ上で書いているように修正ですか?

makoto 2002/02/12(火) 17:11:44
>mbb_str -> mbb_str[0]

これはどこと置きかえるのですか?

TAKA 2002/02/12(火) 17:12:00
すみません上にも書きましたが、
mbb_str -> mbb_str[0]
としてください。
又、wk はunsigned char でお願いしますm(__)m

TAKA 2002/02/12(火) 17:13:27
           if (wk[0] != 0x00) {
                wk[1] = mbb_str[0];
                printf("%s",wk);
                memset( wk, 0, sizeof( wk ));
            }
            else if ((mbb_str[0] & 0x80) == 0x80) {
                wk[0] = mbb_str[0];
            }
            else {
                printf("%s",mbb_str);
            } 
です。たびたびすみません。

makoto 2002/02/12(火) 17:19:49
パターン2を試したところ
"tEsカサ ギ1V;6[q50@eARIU"
と言うような結果が返ってきました。

やはり同じようなところで違う結果が返ってきています。
むー。なぜ??

TAKA 2002/02/12(火) 17:20:13
    while(( fgets( chstr, 6, fp )) != NULL ){  
        pstr = (unsigned char *)chstr;
        memset( wk, 0, sizeof(wk) );

        while ( *pstr ) {
            if (wk[0] != 0x00) {
                wk[1] = *pstr;
                printf("%s",wk);
                memset( wk, 0, sizeof(wk) );
            }
            else if ((*pstr & 0x80) == 0x80) {
                wk[0] = *pstr;
            }
            else {
                printf("%c",*pstr);
            }
                        
            pstr++;
        }
        memset( chstr, 0, sizeof(chstr) );
    }
最後にもう1パターンです。
これでできないはずはない・・・。
でもこれで出来て解決といえるのか・・・?

TAKA 2002/02/12(火) 17:27:26
> パターン2を試したところ
> "tEsカサ ギ1V;6[q50@eARIU"
> と言うような結果が返ってきました。

これは変ですね・・・。
普通は文字化けするはづですが・・・。

とすると
_mbsncpy か _mbsinc がおかしい可能性があります。
デバッグで、きちんとコピーされているか?
又、ポインタがきちんとすすんでいるか?
を確認してみたらいいかもしれません・・・。

makoto 2002/02/12(火) 17:28:03
あーーやっぱりダメです(T_T) 

"tEsカサ ギ1V;6[q50@eARIGat"
結果がこれです。

NGAさん、TAKAさんに
これほどまで考えて頂いているのに。
これはもうプログラムの問題ではないのでしょうか?

NGA 2002/02/12(火) 17:31:00
近況報告です。
でません。

TAKA 2002/02/12(火) 17:33:45
最後のパターンでもだめだということは、何か他に問題あるとおもいます。
OSはなんなのでしょうか?
又、フォントが壊れているとかの可能性がありますね。
中途半端ですが・・・わからないです・・・。

TAKA 2002/02/12(火) 17:39:35
    char chstr[12]; -> chstr[13]
最後にこれだけ試してください。

sara 2002/02/12(火) 17:43:07
横から失礼します。
文字列内容から調べてみました。

"tEsカサ ギ17;6[R50@eARIGat" を16進コードで見ると

74 45 73 83 4A 83 54 20 83 4D 31 82 56 3B 36 5B  : tEsカサ ギ17;6[
82 71 35 30 40 65 41 52 49 82 66 82 81 74        : R50@eARIGat


"tEsカサ ギ1V;6[q50@eARIGat"

74 45 73 83 4A 83 54 20 83 4D 31 56 3B 36 5B 71 : tEsカサ ギ1V;6[q
35 30 40 65 41 52 49 82 66 82 81 74             : 50@eARIGat

これら2つの内容を比較してみると、2箇所 82 というコードが落ちています。
これらがどこで欠落したのかを調べてみてはいかがでしょうか?
@ fgets()実行後の chstr の内容
A _mbsncpy() 実行後の mbb_str の内容
B _mbsinc() 実行後の pstr の内容

これらをバイト単位でダンプしてみるとどこで欠落しているかがはっきりすると思います。

NGA 2002/02/12(火) 17:45:30
大きなバッファに一度で全て読み込んで
"tEsカサ ギ17;6[R50@eARIGat" かどうか見てみては?

VCで "tEsカサ ギ17;6[R50@eARIGat" を書込んでいるテスト用ファイルを
バイナリで開きました。

000000  74 45 73 83 4A 83 54 20  83 4D 31 82 56 3B 36 5B
000010  82 71 35 30 40 65 41 52  49 82 66 82 81 74

makotoさん、同じかどうか見てもらえませんか?
それとファイルパスは間違っていないですよね。

makoto 2002/02/12(火) 17:51:02
まずデバックをして値の変化をみてみました。

fgets()でchstrに読みこんでいる時点で
すでに "V;6[" という値が入ってきていました。

sara 2002/02/12(火) 17:59:16
> fgets()でchstrに読みこんでいる時点で
> すでに "V;6[" という値が入ってきていました。
この直前のfgets()実行後の chstr を文字列ではなくバイトコードで調べてみるとどうなって
いますか?

sara 2002/02/12(火) 18:09:58
もうひとつ確かめてください。
ファイルパスとファイルが壊れていないかの確認です。

char command[256];
sprintf(command, "type %s", argv[1]);
system(command);       // @
printf("\n");          // A

これら4行をファイルを開く前に挿入して、@、Aはファイルを閉じた後にも追加して実行して
みてください。

このように追加すると、プログラム実行中に、コマンドプロンプト上でテキストファイルを読み
出すシステムコールが実行されます。

ぜひお試しください。

makoto 2002/02/12(火) 18:12:46
>この直前のfgets()実行後の chstr を文字列ではなくバイトコードで調べてみるとどうなって
いますか?

' '→32
'キ'→-73
'゛'→-34
'1'→49 

これの他に-126で''でくくられていない
ゴミのようなものがありました。

sara 2002/02/12(火) 18:27:14
> これの他に-126で''でくくられていない
> ゴミのようなものがありました。

 これが欠落していた 0x82 の正体です。
 このコードと次の'V'(0x56)のコードの2バイトで "7"になります。
 このように、マルチバイトの1バイト目であるコードで終わっている場合には、それを次の読
み込みの配列のトップにもってくるか、さらに1バイト分だけ読み込んで処理するかなどの対処
をすれば文字化けもなくなるはずです。

sara 2002/02/12(火) 18:32:20
> 'キ'→-73
> '゛'→-34

と解釈してはいけません。
73と34の2バイトで"ギ"を表しています。
それから、文字コードを見るときは、16進数で表したほうが便利です。

makoto 2002/02/12(火) 19:07:45
[[解決]]
NGAさん、TAKAさん、saraさん。
ありがとうございました。

みなさんのおかげで無事、解決いたしました!
ホントに大感謝です。
お手数をお掛けいたしました。

また何かありましたらよろしくお願いします!
ありがとうございました。

NGA 2002/02/12(火) 19:16:53
すみません。
少し釈然としないものがあるので、
どうして文字化けして、そしてどのように解決したのか詳細が知りたいのですが。

makoto 2002/02/13(水) 09:20:05
おはようございます。

うまく説明できるかわかりませんが
文字化けの原因と解決方法を説明させていただきます。

[読み込む値]:'tEsカサ ギ17;6[R50@eARIGat'

while(( fgets( chstr, 6, fp )) != NULL ){
ここでの chstr の値の変化を順番に示します。

@ 't'|'E'|'s'|'カ'|'サ'
A ' '|'キ'|'゛'|'1'|'★'
B 'V'|・・・

と続きます。

ここで★の部分には'7'の1バイト目が入っています。
saraさんの言っていた、「欠落していた 0x82 」です。

>このコードと次の'V'(0x56)のコードの2バイトで "7"になります。
マルチバイト文字をわけてしまったために文字化けが起こっていました。
 
解決策として chstr の最後にマルチバイトの1バイト目がきていれば
もう1バイト読みこむという処理を加えました。

NGAさん、このような説明で解ってもらえたでしょうか?

私も今回のことでとても勉強になりました。
みなさまありがとうございました。

NGA 2002/02/13(水) 09:32:40
おはようございます。

>while(( fgets( chstr, 6, fp )) != NULL ){
>@ 't'|'E'|'s'|'カ'|'サ'

fgets で6文字読込を指定しているなら、最初の読込では 6 - 1 で5文字読み込まれて
0x74 0x45 0x73 0x83 0x4A 0x00 ("tEsカ")となるはずですが。

TAKA 2002/02/13(水) 09:41:29
それでは解決していないかもしれません・・・。
文字列の2バイトコードの1バイト目とは一種類ではありません。
’サ’の時がいけているのに’7’がいけない理由とは何か?
になると思います。また、1バイト目が欠落しているわけではなく、
続けてprintfで書いてるにかかわらず、でないのは変だと思います。
言語、OSなどに起因するものだと思います。
よろしければ、OSと使用言語をしりたいのですが・・・?
今後、扱う時に考えなければいけない事もありますのでm(__)m

a 2002/02/13(水) 09:45:26

makoto 2002/02/13(水) 09:49:04
私も今気付きましたが
ここでは半角カナは使えないのですよね。

'カサ ギ'
の部分は本当は半角カナなのです。
ずっと全角で表示されているのに気付きませんでした。

この食い違いでNGAさんと結果が違っていたのかもしれませんね。

TAKAさん
1バイト目かどうかの判定は _ismbblead でしています。

環境は VC++,Win98SE です。

TAKA 2002/02/13(水) 10:15:27
現象確認できました。
半角カタカナとは気づきませんでした。
ついでに'7'を全角カタカナにかえてためしてみて動きますか?
ちょっと気になったので・・・。

sara 2002/02/13(水) 10:28:45
> 'キ'→-73
> '゛'→-34
この記述で半角カタカナだと気づくべきでした。

> ついでに'7'を全角カタカナにかえてためしてみて動きますか?
0x82が読み込まれているのだから、これはもともと全角ですよね?

TAKA 2002/02/13(水) 10:32:46
> 0x82が読み込まれているのだから、これはもともと全角ですよね?
はいそうですが、全角カタカナを認識しない関数があるので・・・。
SPパックとかが入っていないと前にどの関数だったか覚えていませんが
認識できなかったことがあったので。
今はSPを入れたので動いていますが(^^)

makoto 2002/02/13(水) 10:33:34
そうですね。
もともと'7'は全角でした。

NGA 2002/02/13(水) 10:35:03
makotoさん、やはり一度テキストをバイナリで開いて16進であげてもらえませんか?

makoto 2002/02/13(水) 11:08:54
すみません。
バイナリで開くと言うのはどうやってやるのでしょう。
普通にファイルを読んで
fprintf(wfp, "%02X ", szMoji);
と16進で書きこめばいいのでしょうか?
これではうまくいかないのですが。

NGA 2002/02/13(水) 11:13:14
VCで[ファイル]→[開く]でファイルを選択し、[用途]をバイナリにしてから[開く]を押しま
す。
それで表示される16進コードをあげてもらえませんか?

makoto 2002/02/13(水) 11:22:14
NGAさん
ありがとうございます。できました。

000000 74 45 73 B6 BB 20 B7 DE   31 82 56 3B 36 5B 82 71
000010 35 30 40 65 41 52 49 82   66 82 81 74

NGA 2002/02/13(水) 11:27:34
カタカナは全て半角だったのですね。

makoto 2002/02/13(水) 11:29:05
はい。
私も気付くのが遅くてすみませんでした。

NGA 2002/02/13(水) 11:31:24
ありがとうございました。
大変すっきりしました。

古いスレッドには追加発言できません。