第11章 演習問題 解答例

11.1 ファイル入出力の基本

a11-1-1.c

色の名前を格納してあるファイル「color.txt」を読み込み、"green"が名前の中にあるもののみファイル「green.txt」に書き込むプログラムを作成してください。

/* a11-1-1.c */
#include <stdio.h>
#include <string.h>

int main(void)
{
    FILE *fin, *fout;
    char str[256];

    if( (fin = fopen("color.txt", "r") ) == NULL) {
        printf("Input file open error.\n");
        return 1;
    }
    if( (fout = fopen("green.txt", "w") ) == NULL) {
        printf("Output file open error.\n");
        fclose(fin);
        return 1;
    }

    while(fgets(str, sizeof(str), fin) != NULL) {
        if (strstr(str, "green") != NULL) {
            fputs(str, fout);
        }
    }

    fclose(fin);
    fclose(fout);

    return 0;
}

[Back]

a11-1-2.c

読み込んだファイルの中身をすべて小文字に書き換えて、別ファイルに保存するプログラムを作成してください。

/* a11-1-2.c */
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    FILE *fin, *fout;
    char infile[40], outfile[40];
    int c;

    printf("コピー元ファイル = ");
    scanf("%39s", infile);
    printf("コピー先ファイル = ");
    scanf("%39s", outfile);
    if( (fin = fopen(infile, "r") ) == NULL) {
        printf("Input file open error.\n");
        return 1;
    }
    if( (fout = fopen(outfile, "w") ) == NULL) {
        printf("Output file open error.\n");
        fclose(fin);
        return 1;
    }

    while( (c = fgetc(fin) ) != EOF) {
        c = tolower(c);
        fputc(c, fout);
    }

    fclose(fin);
    fclose(fout);

    return 0;
}

大文字を小文字に変換するには、tolower関数を使います。

[Back]

a11-1-3.c

キーボードから入力した氏名、身長、体重をファイルに登録するプログラムを作成してください。

/* a11-1-3.c */
#include <stdio.h>

int main(void)
{
    FILE *fp;
    char name[20];
    double height, weight;

    if( (fp = fopen("body.txt", "w") ) == NULL) {
        printf("File open error.\n");
        return 1;
    }

    printf("氏名 身長 体重を入力してください。(終了条件:Ctrl+Z)\n");
    while (scanf("%19s %lf %lf", name, &height, &weight) != EOF) {
        fprintf(fp, "氏名:%-20s 身長:%5.1f 体重:%5.1f\n", 
                    name, height, weight);
    }

    fclose(fp);

    return 0;
}

[Back]

a11-1-4.c

次のように昇順に並んだデータが登録してあるファイル(data.txt)があります。このファイルを読み込み、メジアン(中央値)とモード(最頻値)を求めるプログラムを作成してください。

 data.txt
 6 6 6 12 12 34 56 76 76 87 87 87 92 105 105 105 105 128 128 161

/* a11-1-4.c */
#include <stdio.h>
#define N 100   /* 配列要素数 */

int main(void)
{
    FILE *fp;
    int i, n = 0, mode, count, maxcount;
    int array[N];

    if( (fp = fopen("data.txt", "r") ) == NULL) {
        printf("File open error.\n");
        return 1;
    }

    while (fscanf(fp, "%d", &array[n]) == 1) {
        n++;
        if (n >= N) {
            printf("データ数が%dを超えました。\n", N);
            fclose(fp);
            return 1;
        }
    }

    count = maxcount = 1;
    mode = array[0];
    for (i = 1; i < n; i++) {
        if (array[i - 1] == array[i]) {
            count++;
        }
        else {
            count = 1;
        }
        if (count > maxcount) {
            maxcount = count;
            mode = array[i - 1];
        }
    }
    printf("メジアン = %d\n", array[n / 2]);
    printf("モード = %d\n", mode);

    fclose(fp);

    return 0;
}

メジアンとは、要素を昇順に並べたときに中央に位置する値です。
モードとは、最も多く出現する値です。

[Back]

11.2 テキストファイルとバイナリファイル

a11-2-1.c

P.339の演習1(a10-1-2.c)で使用した構造体をテキストファイルに書き込んだのちに読み込み、さらに画面に表示するプログラムを作成してください。

/* a11-2-1.c */
#include <stdio.h>
#define N 5     /* 人数   */
#define K 5     /* 科目数 */

typedef struct {    /* 成績構造体 */
    int no;           /* 学生番号   */
    char name[20];    /* 氏名       */
    int ten[K];       /* 点数(国語・数学・理科・社会・英語)*/
} Test_record;

int main(void)
{
    FILE *fp;
    Test_record student[N] = 
    {{1, "安部寛之", 76, 82, 87, 93, 88},
     {2, "内山理香", 54, 66, 71, 64, 76},
     {3, "小田裕一", 93, 45, 63, 97, 96},
     {4, "後藤美希", 81, 88, 72, 84, 78},
     {5, "柴崎ユウ", 58, 61, 77, 56, 88}};
    Test_record read[N];
    int i, j;

    /* テキストファイルのオープン */
    if((fp = fopen("txt2.dat", "w+")) == NULL) {
        printf("ファイルがオープンできません\n");
        return 1;
    }
    /* テキストファイルへの出力 */
    for (i = 0; i < N; i++) {
        fprintf(fp, "%d %s ", student[i].no, student[i].name);
        for (j = 0; j < K; j++) {
            fprintf(fp, "%d ", student[i].ten[j]);
        }
        fprintf(fp, "\n");
    }
    /* テキストファイルからの入力 */
    fseek(fp, 0L, SEEK_SET);
    for (i = 0; i < N; i++) {
        fscanf(fp, "%d%s", &read[i].no, read[i].name);
        for (j = 0; j < K; j++) {
            fscanf(fp, "%d", &read[i].ten[j]);
        }
    }
    /* 入力の確認 */
    for (i = 0; i < N; i++) {
        printf("%d %s ", read[i].no, read[i].name);
        for (j = 0; j < K; j++) {
            printf("%d ", read[i].ten[j]);
        }
        printf("\n");
    }

    fclose(fp);

    return 0;
}

[Back]

a11-2-2.c

P.339の演習1(a10-1-2.c)で使用した構造体をバイナリファイルに書き込んだのちに読み込み、さらに画面に表示するプログラムを作成してください。

/* a11-2-2.c */
#include <stdio.h>
#define N 5     /* 人数   */
#define K 5     /* 科目数 */

typedef struct {    /* 成績構造体 */
    int no;           /* 学生番号   */
    char name[20];    /* 氏名       */
    int ten[K];       /* 点数(国語・数学・理科・社会・英語)*/
} Test_record;

int main(void)
{
    FILE *fp;
    Test_record student[N] = 
    {{1, "安部寛之", 76, 82, 87, 93, 88},
     {2, "内山理香", 54, 66, 71, 64, 76},
     {3, "小田裕一", 93, 45, 63, 97, 96},
     {4, "後藤美希", 81, 88, 72, 84, 78},
     {5, "柴崎ユウ", 58, 61, 77, 56, 88}};
    Test_record read[N];
    int i, j;

    /* バイナリファイルのオープン */
    if((fp = fopen("bin2.dat", "w+b")) == NULL) {
        printf("ファイルがオープンできません\n");
        return 1;
    }
    /* バイナリファイルへの出力 */
    fwrite(student, sizeof(Test_record), N, fp);

    /* バイナリファイルからの入力 */
    fseek(fp, 0L, SEEK_SET);
    fread(read, sizeof(Test_record), N, fp);

    /* 入力の確認 */
    for (i = 0; i < N; i++) {
        printf("%d %s ", read[i].no, read[i].name);
        for (j = 0; j < K; j++) {
            printf("%d ", read[i].ten[j]);
        }
        printf("\n");
    }

    fclose(fp);

    return 0;
}

freadとfwriteを使うと、構造体を複数まとめて読み書きすることができます。

[Back]


Copyright© 2006,2012 Tomoko Sugawara. All Rights Reserved.