#pragma twice

KAB-studio > プログラミング > #pragma twice > 231 Version 12.08 TEXT と BYNARY

#pragma twice 231 Version 12.08 TEXT と BYNARY

前のページへ 表紙・目次へ 次のページへ

 Version 12.08
TEXT と BYNARY

忘れたかもしれないけど、 Version 12 のテーマはテキストとバイナリー
です
なんか浮動小数点のイメージが強くて忘れてた……
で、テキストとバイナリーが大きな問題になるのは、ファイルを使った場
合です
ファイル?
ファイルじゃない、つまりメモリに全部データを入れている場合に問題に
ならないのは、そのデータがどういうデータなのかわかるから。 double に
は前回見たようなフォーマットでデータが入ってるわけだから
そんなの当たり前じゃん
逆に言うと、ファイルから取り出した double のデータが、本当に 
double かどうかわかんないってこと
……? わかるでしょ、よくわかんないけど、 double でファイルに書い
て、それを double で取り出せばいいんだから
 double でファイルに書く、っていうのを他のアプリがしたら?
あ……
昔と違って、今はいろんなアプリを組み合わせて使うのが普通だし、ネッ
ト経由でデータだけもらって読み込むってことも多いから、そういった部分
でうまくいかないかもしれないわけ
つまり、 double でファイルに出力するところを、そうしないかもしれな
い、ってわけ?
そういうあからさまに違うのもあるし、ほんのちょっとした細かい違うも
あるし。それに、自分のアプリだけで書き込んで取り出しても、うまくいか
ないこともあるから
へ?
ちょっとした形式違いで失敗するから。で、どういう時にそういう違いが
出るのか、どういう時に気を付けなきゃいけないのかを
これから教わるわけね
そういうこと。で、まずは改行文字について見てみます
改行文字……って、 \n だよね
そう。プログラム上では、 \n でオーケー
プログラム上では……?
ファイル上では違うんです。 Version 9.17 ( No.178 ) を思い出して
あ! そういえば、ファイルの中は改行って \r\n なんだよね……
そう。つまり、プログラムの中では改行文字は \n だけど、ファイルの中
では \r\n ってことです
な、なんか複雑なんですけど……
複雑な理由は、OSごとに改行文字が違うから
違う?
ウィンドウズの改行文字は \r\n だけど、他は違うってこと。 C 言語が
作られた UNIX っていうOSがあるんだけど
リナックスとかは聞いたことあるよ
その系統。この UNIX 系のOSは、テキストファイルの改行コードが \n 
なんです
そっか、そのころなら何も考えずに使えたわけね
ただ、 UNIX 系って言っても色々種類があって、それぞれに改行コードは
違うんだよね。シンプルだから判別も難しくて、文字コードの問題よりも面
倒かも

って言っても、単に改行のところがうまくいかなかったりするだけで、文
字コードよりは楽だけどね
……そういえば、その辺ってプログラムでどうするの? なんか全然気に
してなかったけど
そこがポイント。実は、普通に使う分には改行文字については気にしなく
ていいんです
へー
まず、次のファイルを Data.txt ってファイル名で作って

AAA
BBB

場所は .dsw ファイルが置いてあるところ
ほいできたよ
次に、 Version 5.11 ( No.076 ) を参考にして、ファイルを読み込んで
みます

void ReadTextFile()
{
    // ファイルを開きます。
    FILE *pstFile
        = fopen( "Data.txt", "r" );
    if( !pstFile )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

    while( !feof( pstFile ) )
    {
        TRACE( "%02X\n", fgetc( pstFile ) );
    }

    // ファイルを閉じます。
    fclose( pstFile );
    return;
}

 fgetc() って、1文字ずつ読み込むのだよね
そう、 Version 5.12 ( No.077 ) でやったね。 fgetc() で1文字ずつ取
り込んで、16進数で表示するっていう関数。これを実行するとこう出力さ
れます

41
41
41
0A
42
42
42
ffffffff

最後の ffffffff って?
これは EOF 。 EOF って -1 だから
あ、そーなんだ。って、 EOF まで出しちゃ意味ないんじゃ……
ちゃんとするのなら、 fgetc() の戻り値が EOF ならループ抜ける、って
いう処理の方がいいかもね。ここではテストだから簡単に
そうそう、テストだもんね。で…… 41 と 42 は、16進の A と B だよ
ね。で、改行が……あ、 0A ってことは \n だ
そう、こういうふうに普通にファイルから取ってくると、改行は \r\n 
じゃなくて \n だけ来ます
へー、便利ねー
でも、これが便利じゃない場合もあります
え?
まず、この \r\n が \n になるっていうのは、実はランタイムの機能。 
fgetc() とかを使うと \r\n を自動的に \n に変換してくれます
ランタイムの中に変換機能がある、と
で、問題になるのが、文字列じゃないデータを取ってくるとき。ファイル
の中に \r と同じコード、つまり 0x0D が入っていたら、それも変換され
ちゃう
げ、それはまずいね……
そこで、変換しない方法を使ってみます

void ReadBinaryFile()
{
    // ファイルを開きます。
    FILE *pstFile
        = fopen( "Data.txt", "rb" );
    if( !pstFile )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

    while( !feof( pstFile ) )
    {
        TRACE( "%02X\n", fgetc( pstFile ) );
    }

    // ファイルを閉じます。
    fclose( pstFile );
    return;
}

あれ? さっきと変わらないような……
変わっているのは fopen() の引数

        = fopen( "Data.txt", "rb" );

あ!  b が付いてる!!
この b は binary の b 
あ、ここでバイナリーが出てくるんだ
これを実行してみるとこうなります

41
41
41
0D
0A
42
42
42
FFFFFFFF

 0x0D 、 \r が入ってる!!
つまり、これがファイルの本当の中身。ファイルの中が \r\n で改行され
てるってことがわかったでしょ
ホントは \r\n で改行されてるんだけど、普通に開くと \n ……普通?
つまり fopen() で開くときのデフォルトは、変換するモードってこと。 
b をつけると変換しないモードになるってこと
今まで気にしなかったけど、そういうパラメーターがあったのね
ちなみに、はっきりと〈変換する〉って設定したい場合には、 b の代わ
りに t をセットします

つまり

        = fopen( "Data.txt", "r" );



        = fopen( "Data.txt", "rt" );

は同じってこと
つまり、何も付けてないと t が付いてるのと同じになって、それが変換
モードってことね。あ、 t って何?
 TEXT の t 
そのまんまね
そのまんまなら思いついて欲しいなー
うっ、思いついてたって!

/*
    Preview Next Story!
*/
普通に使ってると、バイナリーっていらなさそう
全体的にはテキストの方向に向かってるかも
え、そうなの?
テキストならどのPCでも見られるし、回線とかが良くなってきたし
じゃあなんかバイナリーっていらない?
音声や画像、圧縮をやるなら必要だよ?
当分やらなさそうだけど
というわけで次回
< Version 12.09 バイナリーモードで書き込む! >
につづく!
でもやっぱ教える
う”
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。