ホーム » スタッフ » 斉藤徹 » 講義録 » プログラム応用 » ファイル入出力

2016年7月
« 6月   8月 »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

最近の投稿(電子情報)

アーカイブ

カテゴリー

ファイル入出力

今日は、ファイル入出力のプログラム演習。

ファイル入出力

 // 基礎的なファイル入力
#include <stdio.h>
void main() {
   FILE* fp ;
   if ( (fp = fopen( "data.txt" , "rt" )) != NULL ) {
      char name[ 100 ] ;
      int age ;

      while( fscanf( fp , "%s%d" , name , &age ) == 2 ) {
         printf( "%s %d\n" , name , age ) ;
      }
      fclose( fp ) ;
   }
}
 // 入力したデータから条件を満たすデータだけを出力
#include <stdio.h>
void main() {
   FILE* fp_in ;
   FILE* fp_out ;

   if ( (fp_in = fopen( "in.txt" , "rt" )) != NULL ) {
      if ( (fp_out = fopen( "out.txt" , "wt" )) != NULL ) {
         char name[ 100 ] ;
         int  age ;

         while( fscanf( fp_in , "%s%d" , name , &age ) == 2 ) {
            if ( age >= 18 )
               fprintf( fp_out , "%s %d\n" , name , age ) ;
         }
         fclose( fp_out ) ;
      }
      fclose( fp_in ) ;
   }
}

テキストモードとバイナリモード

前述プログラムでは、fopen のファイルモードで、"rt" , "wt" のように 文字"t"をつけている。これは、OSによる行末文字の取り扱いの トラブルを防ぐためのもの。

OSの成り立ちの違いで、Windows と Unix では、行末文字の取り扱い方法 が違う。

Windows では、次の行の先頭に移動するには、"\r"(キャリッジリターン)と "\n"(ラインフィード)が必要となる。

一方、Unix では、次の行の先頭に移動するには、"\n"(ラインフィード)だけ でいい。

この違いがあるため、Unixで開発されたC言語で書いたプログラムを Windows で動かそうとすると、

                       // Unix    Windows
printf( "Hello\n" ) ; // Hello    Hello
printf( "World\n" ) ; // World         World

と異なる表示になってしまう。これでは、WindowsでC言語を書く場合は、 printf( "Hello\r\n" ) といった書き換えが必要になってしまう。

これを防ぐために、fopen で "…t" 書くことで「テキストモード」に 指定すると Windows で printf( "\n" ) を出力すれば、 "\r\n" に変換して出力してくれる。入力時にも同様に、"\r\n" があると、 "\n" に変換してくれる。

絶対PATHと相対PATH

前述のプログラムで、fopen( "data.txt" , "rt" ) と指定すると、 プログラムの保存しているディレクトリと同じ場所から、"data.txt" を 探そうとする。(相対PATH)

しかし、別のディレクトリにあるデータを読む場合には、 場所を明記するために、Z:\directory\data.txt のように、 ルートディレクトリからの場所(Windowsではドライブ名付きで)を 指定する。(絶対PATH)

ただし、Windows でのディレクトリ区切り文字 '\' は、C言語の文字列内では、 特殊文字を指定する時に使われる。このため、文字列内では \\ の様に 書く必要がある。

 fp = fopen( "Z:\\directory\\data.txt" , "rt" ) ;

この場合、"\\"と2重で書くことで、Unix と Windows のプログラムの 書き換えが必要となるのを防ぐため、上例は、Unixのディレクトリ区切り文字"/"を使って、以下のように書いても良い。

 fp = fopen( "Z:/directory/data.txt" , "rt" ) ;