ファイル入力


ファイルから読込む関数には、fscanf 関数があります。これも scanf 関数の先頭に f がついただけなので、使い方は予想できますね。
int fscanf(
           FILE *stream,
           const char *format [, argument ]...                                            
           );
が必要です。stream にはファイル構造体へのポインタを指定します。format には変換指定子を指定し、argument には引数を指定します。この関数は、file の終端まで来たら EOF を返します。

ソースコード

源文件
  1|/* readfile01.c */
  2|
  3|#include <stdio.h>
  4|#include <string.h>  /* strcat関数で必要 */
  5|
  6|int main(void)
  7|{
  8|  FILE *fp;
  9|  char filename[256], name[16], tel[16];
 10|  char *format = "%-15s %-15s\n";
 11|
 12|  printf("ファイル名(拡張子不要)--");
 13|  scanf("%s", filename);
 14|  strcat(filename, ".txt");
 15|  fp = fopen(filename, "r");
 16|
 17|  if(fp == NULL){
 18|    perror("ファイルをオープンできません\n");                                         
 19|    return -1;
 20|  }
 21|
 22|  while (fscanf(fp, "%s%s", name, tel) != EOF)
 23|    printf(format, name, tel);
 24|
 25|  fclose(fp);                                                                         
 26|  return 0;
 27|}

実行結果

ファイル名(拡張子不要)--text  
河野          080-1234-5678  
山田          080-9999-0120080-6666-8888000-5555-5555  
徐鋭          070-1111-1111  
このプログラムで他のテキストファイルを読込むとどうなるでしょうか。なんとか読めるが、表示が可笑しくなっていますね。text.txt では、決まった形式でデータが書込まれています。

readfile01.c では、これらを name, tel の配列に読込んでいます。

%s で読込んだ文字列が name や tel の配列に収まりからないことも考えられます

一般的なテキストファイルを読み込むには、1文字読んでは1文字表示する、という方式のほうが安全です。



ソースコード

源文件
  1|/* readfile01x.c */
  2|
  3|#include <stdio.h>
  4|#include <string.h>  /* strcat関数で必要 */
  5|
  6|int main(void)
  7|{
  8|  FILE *fp;
  9|  char filename[256];
 10|  char c;                                                                             
 11|
 12|  printf("ファイル名(拡張子不要)--");
 13|  scanf("%s", filename);
 14|  strcat(filename, ".txt");
 15|  fp = fopen(filename, "r");
 16|
 17|  if(fp == NULL){
 18|    perror("ファイルをオープンできません\n");
 19|    return -1;
 20|  }
 21|
 22|  while (fscanf(fp, "%c", &c) != EOF)
 23|    printf("%c", c);
 24|
 25|  fclose(fp);                                                                         
 26|  return 0;
 27|}


他にも、適当なテキストファイルを読込んでみてください。正しく読込めます。
さて、このプログラムをもう少しスマートに書き直してましょう。

ソースコード

源文件
  1|/* readfile02.c */
  2|
  3|#include <stdio.h>                                                                    
  4|#include <string.h>  /* strcat関数で必要 */
  5|
  6|int main(void)
  7|{
  8|  FILE *fp;
  9|  char fname[256];
 10|
 11|  int c;
 12|
 13|  printf("ファイル名(拡張子不要)--");
 14|  scanf("%s", fname);
 15|  //  fp = fopen(strcat (gets (fname), ".txt"), "r");                                 
 16|  fp = fopen(strcat (fname, ".txt"), "r");
 17|
 18|  if(fp == NULL){
 19|    perror("ファイルをオープンできません\n");
 20|    return -1;
 21|  }
 22|
 23|  while ((c = fgetc(fp)) != EOF)
 24|    putc(c, stdout);
 25|                                                                                      
 26|  return 0;
 27|}

「あれ?」と思われたところは15行目の「fopen(strcat(gets(fname), ".txt"), "r")」のところではないでしょうか

gets(fname); でユーザーがファイル名(拡張子なし)を入力します。gets の戻り値は fname なのです。したがってこれは、fopen(strcat(fname, ".txt"), "r")と同じです。

次に、strcatで拡張子なしのファイル名に「.txt」が付加されました。strcatの戻り値は追加先の文字列です。したがって fopen(fname(.txtが追加されえいる), "r")と同じなのです。

次に fgetc 関数はファイルから1文字ずつ読込みます。

int fgetc(
          FILE *stream                                                                    
          );
これは、streamから1文字読込んで int 型で返す関数です。 が必要です。ファイルの終端まで来たら EOF を返します。

put 関数はファイル文字を出力します。

int putc(
         int c,
         FILE *stream                                                                     
         );

put 関数は、stream に c の1文字を出力します。

Chapte9 @ C言語目録 @ HomeWork List @ 昭亮's Homepage