C 言語でのファイルリダイレクトの使用

胡金庫 2023年10月12日
C 言語でのファイルリダイレクトの使用

この記事では、C 言語でファイルリダイレクトを使用する方法をいくつか説明します。

標準入力をリダイレクトするために < 演算子を使用する

ファイルリダイレクトは一般的に UNIX ベースのシステムでは I/O リダイレクトとして知られており、標準入力がどこから来るのか、標準出力がどこに行くのかを再定義することができます。演算子 < は、標準入力がどこから来るかを変更するために使用されます。この方法は、ファイルの内容からユーザの入力を取り出してプログラムバッファに格納するのに便利です。この場合、改行文字が見つかるまでファイルの内容を読み込むために fgets 関数を利用します。改行文字が読み込まれると、それもまた与えられたバッファに格納され、その後に文字列終端のヌルバイトが格納されます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#define SIZE 1000

int main(int argc, char *argv[]) {
  char buf[SIZE];
  printf("Write input text: ");
  fgets(buf, SIZE, stdin);
  printf("%s\n", buf);

  exit(EXIT_SUCCESS);
}

サンプルコマンド:

./program < input.txt

出力:

The first line from the input.txt file

先ほどのサンプルコードでは、ハードコードされた値を持つバッファを割り当てました。しかし、ユーザから提供された入力ファイルを格納するためには、より多くのメモリが必要となる場合があり、シナリオに合わせて適応的な方法を実装する必要があります。そのためには、malloc を用いて動的メモリを確保し、ファイルの 1 行目を格納するのに必要な最大数としてファイルサイズの合計を渡す。この方法では、与えられたファイルが大きすぎて、最初の行が短い場合、メモリを浪費しすぎてしまう可能性があります。しかし、malloc が失敗せず、システムメモリが枯渇しない限り、コードが最も長い行を読み込めることは保証されています。

注意してほしいのは、stat システムコールを使ってファイルサイズを取得していますが、これには入力ファイルのパス名が必要で、コマンドライン引数として明示的に指定しないと取得できないということです。しかし、fgets が初期化されていないメモリ領域に書き込もうとしたり、プログラムが失敗して終了したりしないようにするためには、すべての関数呼び出しが正常に戻るかどうかをチェックする必要があることに注意してください。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
  char *buffer = NULL;
  const char *filename = NULL;
  struct stat sb;

  if (argc != 2) {
    printf("Usage: ./program filename < filename\n");
    exit(EXIT_FAILURE);
  }

  filename = argv[1];

  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  buffer = malloc(sb.st_size);
  if (!buffer) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }

  printf("Write input text: ");
  if (fgets(buffer, sb.st_size, stdin) == NULL) {
    perror("fgets");
    exit(EXIT_FAILURE);
  }
  printf("%s\n", buffer);

  exit(EXIT_SUCCESS);
}

サンプルコマンド:

./program input.txt < input.txt

出力:

The first line from the input.txt file
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C File