「C言語の基礎 - ファイル」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
639行目: 639行目:
  </source>
  </source>
<br><br>
<br><br>
== 一時的なバイナリファイルを作成する ==
C言語で、一時的なバイナリファイルを作成するには、stdio.hのtmpfile関数を使用する。<br>
<br>
tmpfile関数は、既存のファイルとは異なる一時的なバイナリファイルを作成する関数である。<br>
tmpfile関数で作成したバイナリファイルは、作成時に更新モード ("wb+") でオープンされる。<br>
また、生成したファイルは、ファイルのクローズ時またはプログラムの終了時に自動的に削除される。<br>
<br>
tmpfile関数は、操作が成功した場合は作成したファイルへのポインタを返し、操作が失敗した場合はNULLを返す。<br>
<source lang="c">
#include <stdio.h>
FILE *tmpfile(void);
</source>
<br>
以下の例では、tmpfile関数を使用して、一時的なバイナリファイルを作成してデータを書き込んだ後、そのファイルからデータを読み込んで表示している。<br>
<source lang="c">
#include <stdio.h>
#include <stdlib.h>
#define N 256
int main(void)
{
    char readline[N] = {'\0'};
    FILE *fp;
    /* 一時ファイルの作成 */
    if ( (fp = tmpfile()) == NULL )
    {
      fprintf(stderr, "一時ファイルの作成に失敗しました.\n");
      return EXIT_FAILURE;
    }
    /* 一時ファイルに適当に文字列を書き込む */
    for (int i = 0; i < 5; i++ )
    {
      fprintf(fp, "test%d\n", i);
    }
    /* 念のためバッファフラッシュする */
    fflush(fp);
    /* ファイル位置表示子を戻す */
    rewind(fp);
    /* 一時ファイルから文字列を読み込む */
    while ( fgets(readline, N, fp) != NULL )
    {
      fprintf(stdout, "%s", readline);
    }
    /* 一時ファイルのクローズ(削除) */
    fclose(fp);
    return EXIT_SUCCESS;
}
</source>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:C]]
[[カテゴリ:C]]

2020年5月1日 (金) 09:44時点における版

ファイルを移動する

C言語で、ファイルを移動するには、stdio.hのrename関数を使用する。

rename関数は、oldが指すファイルをnewが指す文字列を名前とするファイルとして識別できるようにする関数である。
oldとnewがそれぞれ異なるディレクトリのファイル名を指している場合には、ファイルの移動が行われる。

rename関数は、ファイル名の変更が成功した場合は0、ファイル名の変更に失敗した場合は0以外の値を返す。
rename関数を呼び出す前に既にファイル名がnewであるファイルが存在している場合、rename関数の動作は処理系定義となるので注意する。

 #include <stdio.h>
 
 int rename (const char *old, const char *new);


以下の例では、rename関数を使用してファイルを移動している。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    char old[] = "./01/sample.txt";
    char new[] = "./02/sample.txt";
 
    if ( rename(old, new) == 0 )
    {
       printf("%sを%sに移動しました.\n", old, new);
    }
    else
    {
       fprintf(stderr, "%sの移動に失敗しました.\n", old);
    }
 
    return EXIT_SUCCESS;
 }



ファイル名を変更する

C言語で、ファイルの名前を変更するには、stdio.hのrename関数を使用する。

rename関数は、oldが指すファイルをnewが指す文字列を名前とするファイルとして識別できるようにする関数である。
oldとnewが同じディレクトリのファイル名を指している場合は、ファイル名の変更が行われる。

rename関数は、ファイル名の変更が成功した場合は0、ファイル名の変更に失敗した場合は0以外の値を返す。
rename関数を呼び出す前に既にファイル名がnewであるファイルが存在している場合、rename関数の動作は処理系定義となるので注意する。

 #include <stdio.h>
 
 int rename (const char *old, const char *new);


以下の例では、rename関数を使用してファイル名を変更している。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    char old[] = "sample01.txt";
    char new[] = "sample02.txt";
 
    if ( rename(old, new) == 0 )
    {
       printf("%sの名前を%sに変更しました.\n", old, new);
    }
    else
    {
       fprintf(stderr, "%sのリネームに失敗しました.\n", old);
    }
 
    return EXIT_SUCCESS;
 }



ファイルを削除する

C言語で、ファイルを削除するには、stdio.hのremove関数を使用する。

remove関数は、filenameが指すファイルを削除する関数である。
remove関数は、ファイルの削除が成功した場合は0、ファイルの削除に失敗した場合は0以外の値を返す。
既にファイルがオープンされている場合のremove関数の動作は、処理系定義になるので注意する。

 #include <stdio.h>
 
 int remove (const char *filename);


以下の例では、remove関数を使用してファイルを削除している。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    char filename[] = "sample.txt";
 
    if ( remove(filename) == 0 )
    {
       printf("%sの削除が完了しました.\n", filename);
    }
    else
    {
       fprintf("stderr, %sの削除に失敗しました.\n", filename);
    }
 
    return EXIT_SUCCESS;
 }



ファイルを開く

ファイルに対して読み書きを行うためには、まず、ファイルを開く必要がある。
C言語で、ファイルを開くには、stdio.hのfopen関数を使用する。

fopen関数は、filenameで指定されたファイルを開いて、そのファイルにストリームを結び付ける関数である。
modeにはモード(開くファイルの種類やデータの読み書きの方法)を指定する。
fopen関数は、ファイルのオープンに成功した場合は、オープンしたストリームを制御するオブジェクトへのポインタを返し、失敗した場合は、NULLを返す。

 #include <stdio.h>
 
 FILE * fopen(const char * restrict filename, const char * restrict mode);


第2引数のmodeに指定できるモードは以下の通りである。

モード ファイル 機能 ファイルが存在しない場合の動作
r テキスト 読み込み エラー
w テキスト 書き込み 新規作成
a テキスト 追加書き込み 新規作成
rb バイナリ 読み込み エラー
wb バイナリ 書き込み 新規作成
ab バイナリ 追加書き込み 新規作成
r+ テキスト 更新(読み込みおよび書き込み) エラー
w+ テキスト 更新(読み込みおよび書き込み) 新規作成
a+ テキスト 更新(追加書き込み) 新規作成
rb+ または r+b バイナリ 更新(読み込みおよび書き込み) エラー
wb+ または w+b バイナリ 更新(読み込みおよび書き込み) 新規作成
ab+ または a+b バイナリ 更新(追加書き込み) 新規作成


fopen関数を使用したファイルのオープンは、多くの場合、以下のような記述で実装される。
以下の例では、sample.txtファイルを書き込みモードでオープンしている。

 char *filename = "sample.txt";
 FILE *fp;
 
 /* ファイルのオープン */
 if ((fp = fopen(filename, "w")) == NULL)
 {
    /* エラー処理 */
 }
 
 /* 何らかの処理 */
 
 /* ファイルのクローズ */
 fclose(fp);


以下の例では、fopen関数を使用して、ファイルを書き込みモードでオープンしている。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
 
    /* ファイルのオープン */
    if ((fp = fopen(filename, "w")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    printf("ファイルのオープンに成功しました.\n");
    printf("/*\n");
    printf(" 普通はファイルに対して書き込みを行うコードを\n");
    printf(" ここに書きます.\n");
    printf("*/\n");
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



ファイルを閉じる

読み書き等の処理が終わったファイルはクローズする。
C言語で、ファイルをクローズするには、stdio.hのfclose関数を使用する。

fclose関数は、streamが指すストリームに結び付けられたファイルをクローズする関数である。
fclose関数は、操作が成功した場合は0、失敗した場合はEOFを返す。

 #include <stdio.h>
 
 int fclose(FILE *stream);


以下の例では、fclose関数を使用してファイルをクローズしている。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
 
    /* ファイルのオープン */
    if ((fp = fclose(filename, "w")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /* ファイルのクローズ */
    fclose(fp);
 
    printf("ファイルをクローズしました.\n");
 
    return EXIT_SUCCESS;
 }



ファイルをクローズしてから新しいファイルをオープンする

C言語で、ファイルをクローズしてから新しいファイルをオープンするには、freopen関数を使用する。
fopen関数とfclose関数を組み合わせて使用してもよいが、freopen関数は、1度の呼び出しでこれらの処理を行うため、短く記述できる。

freopen関数は、streamが指す既存のストリームをクローズしてから、filenameが指すファイルをmodeが指すモードでオープンして、
そのファイルにストリームを結び付ける関数である。
(指定可能なモードについては、fopen関数と同様である。詳しくは、上記のfopen関数のモードを参照すること)

freopen関数は、操作が成功した場合は、オープンしたストリームを制御するオブジェクトへのポインタを返し、失敗した場合はNULLを返す。

 #include <stdio.h>
 
 FILE * freopen(const char * restrict filename, const char * restrict mode, FILE * restrict  stream);


以下の例では、freopen関数を使用して、ファイルをクローズしてから新しいファイルをオープンしている。

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #define N 256
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
    char *writeline = "I don't want to march as much as possible.";
    char readline[N] = {'\0'};
 
    /* ファイルを書き込みモードでオープン */
    if ((fp = fopen(filename, "w")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /* 文字列をsample.txtに書き込む */
    fputs(writeline, fp);
 
    /* ファイルをクローズし, 読み込みモードで再オープン */
    if ((fp = freopen(filename, "r", fp)) == NULL)
    {
       fprintf(stderr, "%sの再オープンに失敗しました.\n 詳細:%s", filename, strerror(errno));
 
       exit(EXIT_FAILURE);
    }
 
    /* ファイルの終端まで文字を読み取り表示する */
    fgets(readline, N, fp);
    puts(readline);
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



ファイルから1文字ずつ文字を読み込む

C言語で、ファイルから1文字ずつ文字を読み込むには、stdio.hのfgetc関数またはgetc関数(マクロ)を使用する。

fgetc関数は、streamが指すストリームから1文字分文字を読み取る関数である。
getc関数は、基本的にはfgetc関数と同様だが、処理系によっては関数ではなくマクロとして実装されている場合がある。

fgetc関数とgetc関数は、ストリームから正常に文字を読み取った場合は、読み取った文字を返す。
読み取りに失敗した場合やファイルの終端を読み取った場合は、EOFを返す。

 #include <stdio.h>
 
 int fgetc(FILE *stream);
 
 int getc(FILE *stream);


以下の例では、fgetc関数を使用して、ファイルの終端まで文字を読み取っている。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
    int ch;
 
    /* ファイルのオープン */
    if ((fp = fopen(filename, "r")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /* ファイルの終端まで文字を読み取り表示する */
    while (( ch = fgetc(fp)) != EOF )
    {
       putchar(ch);
    }
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



ファイルから1行ずつ文字列を読み込む

C言語で、ファイルから1行ずつ文字列を読み込むには、stdio.hのfgets関数を使用する。

fgets関数は、streamが指すストリームから改行文字またはファイルの終わりまで文字列を読み取り、sが指す配列に格納する関数である。
なお、n - 1が1行の最大入力文字数となる。
fgets関数は、ストリームから正常に文字列を読み取った場合は、読み取った文字列を返す。
読み取りに失敗した場合やファイルの終端を読み取った場合は、NULLを返す。

 #include <stdio.h>
 
 char *fgets (char * restrict s, int n, FILE * restrict stream);


以下の例では、fgets関数を使用して、ファイルの終端まで文字列を読み取っている。

 #include <stdio.h>
 #include <stdlib.h>
 
 #define N 256
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
    char readline[N] = {'\0'};
 
    /* ファイルのオープン */
    if ((fp = fopen(filename, "r")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /* ファイルの終端まで文字を読み取り表示する */
    while ( fgets(readline, N, fp) != NULL )
    {
       printf("%s", readline);
    }
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



ファイルに1文字ずつ文字を書き込む

C言語で、ファイルに1文字ずつ文字を書き込むには、stdio.hのfputc関数またはputc関数(マクロ)を使用する。

fputc関数は、streamが指すストリームに、cで指定した文字を書き込む関数である。
putc関数は、基本的にはfputc関数と同じであるが、処理系によっては、関数ではなくマクロとして実装されている場合がある。

fputc関数とputc関数は、ストリームに正常に文字を書き込むことができた場合は書き込んだ文字を返し、書き込みに失敗した場合はEOFを返す。

 #include <stdio.h>
 
 int fputc(int c, FILE *stream);
 
 int putc(int c, FILE *stream);


以下の例では、fputc関数を使用して、キーボードから入力された文字をファイルに書き込んでいる。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
    int c;
 
    /* ファイルのオープン */
    if ((fp = fopen(filename, "w")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /* 入力された文字をsample.txtに出力 */
    while ((c = fgetc(stdin)) != EOF)
    {
       fputc(c, fp);
    }
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



ファイルに1行ずつ文字列を書き込む

C言語で、ファイルに1行ずつ文字列を書き込むには、stdio.hのfputs関数を使用する。

fputs関数は、streamが指すストリームにsが指す文字列を書き込む関数である。
fputs関数は、ストリームに正常に文字列を書き込むことができた場合は正の値を返し、書き込みに失敗した場合はEOFを返す。

 #include <stdio.h>
 
 int fputs(const char * restrict s, FILE * restrict stream);


以下の例では、fputs関数を使用して、文字列をファイルに書き込んでいる。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    FILE *fp;
    char *filename  = "sample.txt";
    char *writeline = "I don't want to march as much as possible.";
 
    /* ファイルのオープン */
    if ((fp = fopen(filename, "w")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /* 文字列をsample.txtに書き込む */
    fputs(writeline, fp);
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



書式文字列に従ってファイルに文字列を書き込む

printf関数のように、書式文字列に従ってファイルに文字列を書き込むには、stdio.hのfprintf関数を使用する。

fprintf関数は、formatが指す書式文字列に従って、streamが指すストリームへ書き込みを行う関数である。
なお、formatに指定できる書式文字列は、printf関数と同じである。

fprintf関数は、ストリームに正常に文字列を書き込むことができた場合は書き込んだ文字数を返し、書き込みに失敗した場合は負の値を返す。

 #include <stdio.h>
 
 int fprintf(FILE * restrict stream, const char * restrict format, ...);


以下の例では、fprintf関数を使用して、文字列をファイルに書き込んでいる。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    FILE *fp;
    char filename[] = "sample.txt";
    int count = 0;
 
    /* ファイルオープン */
    if ((fp = fopen(filename, "w")) == NULL)
    {
       fprintf(stderr, "ファイルのオープンに失敗しました.\n");
 
       return EXIT_FAILURE;
    }
 
    /* 書き込み */
    count = fprintf(fp, "マンガ %s は %d 年に誕生しました.\n", "ピーナッツ", 1950);
    if ( count < 0 )
    {
       fprintf(stderr, "ファイルの書込みに失敗しました.\n");
       fclose(fp);
 
       return EXIT_FAILURE;
    }
 
    fprintf(stdout, "%s へ %d 文字 (byte) 出力しました.\n", filename, count);
 
    /* ファイルクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



バイナリファイルからデータを読み込む

C言語で、バイナリファイルからデータを読み込むには、stdio.hのfread関数を使用する。

fread関数は、streamが指すストリームから、sizeバイト単位でnmemb個のデータを読み込み、ptrが指す配列に格納する関数である。

fread関数は、ストリームから正常にデータを読み取った場合は、読み取った要素の個数を返す。
読み取りに失敗した場合やファイルの終端を読み取った場合は、nmembより小さい値を返す。
※バイナリファイルを扱う場合は、fopen関数でファイルをオープンする際に、バイナリモードでオープンする必要がある。

 #include <stdio.h>
 
 size_t fread (void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream);


以下の例では、fread関数を使用して、バイナリファイルからデータを読み込んでいる。

 #include <stdio.h>
 #include <stdlib.h>
 
 #define N 256
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
    int ptr[N];
    size_t size;
 
    /* ファイルのオープン */
    if ((fp = fopen(filename, "rb")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /*  読み込む */
    size = fread(ptr, sizeof(int), 6, fp);
 
    for (int i = 0; i < size; i++)
    {
       printf("%d\n",  ptr[i]);
    }
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



バイナリファイルにデータを書き込む

C言語で、バイナリファイルにデータを書き込むには、stdio.hのfwrite関数を使用する。

fwrite関数は、ptrが指す配列から、sizeバイト単位でnmemb個のデータをstreamが指すストリームに書き込む関数である。

fwrite関数は、ストリームに正常にデータを書き込むことができた場合は書き込んだ要素の個数を返し、
書き込みに失敗した場合はnmembより小さい値を返す。
※バイナリファイルを扱う場合は、fopen関数でファイルをオープンする際に、バイナリモードでオープンする必要がある。

 #include <stdio.h>
 
 size_t fwrite (const void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream);


以下の例では、fwrite関数を使用して、バイナリファイルにデータを書き込んでいる。

 #include <stdio.h>
 #include <stdlib.h>
 
 int main(void)
 {
    FILE *fp;
    char *filename = "sample.txt";
    int ptr[] = {1, 255, 0x01, 0xff};
 
    /* ファイルのオープン */
    if ((fp = fopen(filename, "wb")) == NULL)
    {
       fprintf(stderr, "%sのオープンに失敗しました.\n", filename);
 
       exit(EXIT_FAILURE);
    }
 
    /* ファイルにデータを書き込む */
    fwrite(ptr, sizeof(int), 4, fp);
 
    /* ファイルのクローズ */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }



一時的なバイナリファイルを作成する

C言語で、一時的なバイナリファイルを作成するには、stdio.hのtmpfile関数を使用する。

tmpfile関数は、既存のファイルとは異なる一時的なバイナリファイルを作成する関数である。
tmpfile関数で作成したバイナリファイルは、作成時に更新モード ("wb+") でオープンされる。
また、生成したファイルは、ファイルのクローズ時またはプログラムの終了時に自動的に削除される。

tmpfile関数は、操作が成功した場合は作成したファイルへのポインタを返し、操作が失敗した場合はNULLを返す。

 #include <stdio.h>
 
 FILE *tmpfile(void);


以下の例では、tmpfile関数を使用して、一時的なバイナリファイルを作成してデータを書き込んだ後、そのファイルからデータを読み込んで表示している。

 #include <stdio.h>
 #include <stdlib.h>
 
 #define N 256
 
 int main(void)
 {
    char readline[N] = {'\0'};
    FILE *fp;
 
    /* 一時ファイルの作成 */
    if ( (fp = tmpfile()) == NULL )
    {
       fprintf(stderr, "一時ファイルの作成に失敗しました.\n");
 
       return EXIT_FAILURE;
    }
 
    /* 一時ファイルに適当に文字列を書き込む */
    for (int i = 0; i < 5; i++ )
    {
       fprintf(fp, "test%d\n", i);
    }
 
    /* 念のためバッファフラッシュする */
    fflush(fp);
 
    /* ファイル位置表示子を戻す */
    rewind(fp);
 
    /* 一時ファイルから文字列を読み込む */
    while ( fgets(readline, N, fp) != NULL )
    {
       fprintf(stdout, "%s", readline);
    }
 
    /* 一時ファイルのクローズ(削除) */
    fclose(fp);
 
    return EXIT_SUCCESS;
 }