10_ファイル出力.md
ファイル出力の手順
- ファイルのオープン
- 読み書き
- ファイルのクローズ
ストリーム
- 入出力にはストリームという概念が存在する。
- ストリームは、情報の流れであり、流れはファイルからファイルに流れていく。
- キーボードや画面も広い意味ではファイルである。
- 画面に文字列を出力したい場合は、画面のファイルに出力を流してやればよい。
fprintf(stdout, "テスト。\n"); // stdoutは標準出力のファイルポインタ
- ちなみに、標準入力は
stdin
,標準エラーはstderr
と定義されている。
ファイルのオープン
fopen関数
FILE *fopen(
const char *filename,
const char *mode
);
- 第二引数の
mode
に関しては下記のオープンモードの一覧を参照
mode文字列 |
説明 |
r |
読み出し用にオープン。指定したファイルが存在しないとき、関数は失敗する。 |
w |
書き込み用にオープン。指定したファイルがすでに存在するときはこれに上書きされる。 指定したファイルが存在しない場合は、新規に作られる。 |
a |
すでに存在するファイルに追加する。指定したファイルが存在しなければ新規に作成。 |
r+ |
ファイル読み込み、更新モード。ファイルが存在しないときは、関数は_失敗する。_ |
w+ |
読み出し、書き込みモードでオープン。ファイルが存在すると上書きされる。 |
a+ |
読み出し、追加・更新モード |
wb |
バイナリで書き込み |
rb |
バイナリで読み込み |
ab |
バイナリで追加 |
- 戻り値の
FILE*
は、FILE構造体へのポインタである。
- 関数が失敗するとNULLが返されるので、必ず戻り値をチェックしてから、次の作業に移ること。
ファイルのクローズ
- ファイルのクローズにはfclose関数を使用する。
fclose関数
int flose(
FILE *stream
)
ファイルの書き込み
fprintf関数
int fprintf(
FILE *stream,
const char *format[,
argument:...
);
サンプルコード
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int myWrite(FILE *);
int main(){
FILE *fp;
char fileName[256];
printf("ファイル名(拡張子不要)--- ");
gets_s(fileName);
strcat_s(fileName, ".txt"); /*文字列を連結*/
errno_t error = 0;
error = fopen_s(&fp, fileName, "a"); /*追加モード*/
if (fp == NULL){
perror("ファイルのオープンに失敗しました。\n");
return -1;
}
while (!myWrite(fp));
fclose(fp);
system("pause");
return 0;
}
int myWrite(FILE *file){
char name[16];
char tel[16];
char yesNo[8];
char *format = "%-15s\t%-15s\n";
printf("氏名-- ");
gets_s(name);
printf("電話-- ");
gets_s(tel);
printf(format, name, tel);
printf("このデータを書き込みますか(y/n): ");
gets_s(yesNo);
if (strcmp(yesNo, "Y") == 0 || strcmp(yesNo, "y") == 0){
fprintf_s(file, format,name,tel);
}
printf("さらにデータを入力しますか?(y/n): ");
gets_s(yesNo);
if (strcmp(yesNo, "N") == 0 || (strcmp(yesNo, "n") == 0)){
return -1;
}
return 0;
}
出力結果
ファイル名(拡張子不要)--- file
氏名-- 山田
電話-- 000-0000-0000
山田 000-0000-0000
このデータを書き込みますか(y/n): y
さらにデータを入力しますか?(y/n): y
氏名-- 鈴木
電話-- 111-1111-1111
鈴木 111-1111-1111
このデータを書き込みますか(y/n): y
さらにデータを入力しますか?(y/n): y
氏名-- 佐藤
電話-- 222-2222-2222
佐藤 222-2222-2222
このデータを書き込みますか(y/n): n
さらにデータを入力しますか?(y/n): n
続行するには何かキーを押してください . . .
山田 000-0000-0000
鈴木 111-1111-1111
ファイルの読み込み(ファイル入力)
fscanf関数
int fscanf(
FILE *stream,
const char *format[, argument]...
);
サンプルプログラム
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
FILE *fp;
char fileName[256];
int c;
printf("ファイル名(拡張子不要)-- ");
gets_s(fileName);
strcat_s(fileName, ".txt");
errno_t error;
error = fopen_s(&fp, fileName, "r");
if (error != 0){
perror("ファイルをオープンできませんでした。");
system("pause");
return -1;
}
while (fscanf_s(fp, "%c", &c) != EOF){
printf("%c", c);
}
fclose(fp);
system("pause");
return 0;
}
出力結果
ファイル名(拡張子不要)-- file
山田 000-0000-0000
鈴木 111-1111-1111
続行するには何かキーを押してください . . .
fgetc関数
int fgetc(
FILE *stream
)
putc関数
int putc(
int c,
FILE *stream
)
- putc関数は、streamにcの1文字を出力する。
サンプルコード
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
FILE *fp;
char fileName[256];
int c;
printf("ファイル名(拡張子不要)--- ");
gets_s(fileName);
strcat_s(fileName, ".txt");
errno_t error = fopen_s(&fp, fileName, "r");
if (error != 0){
perror("ファイルがオープンできません\n");
system("pause");
return -1;
}
c = fgetc(fp);
while (c != EOF){
putc(c, stdout); //標準出力にcを出力
c = fgetc(fp);
}
system("pause");
return 0;
}
出力結果
ファイル名(拡張子不要)--- file
山田 000-0000-0000
鈴木 111-1111-1111
続行するには何かキーを押してください . . .
シーケンシャルアクセスとランダムアクセス
シーケンシャルアクセス
ランダムアクセス
fseek関数
ing fseek(
FILE *stream,
long offset,
int origin
);
stream
にはFILE構造体へのポインタを指定する。
offset
には、origin
からのバイト数を指定する。
origin
には、初期位置を指定する。
- 数値で指定してもよいが、下記の定数を利用することも可能。
定数 |
意味 |
SEEK_CUR |
現在位置 |
SEEK_END |
ファイルの終端 |
SEEK_SET |
ファイルの先頭 |
- 今回の例では、フォーマットが
%-15s\t%-15s\n
のため
15byte + 8byte + 15byte + 2byte=40byte
であるため、
n番目のデータは、40*(n-1)
バイト目からということになる。
- 以降はうまくいかなかったので打ち切り