見出し画像

C言語で Java Silver レベルの問題を作ってみる No.22

 プログラミング言語って、しばらく触れてないと細かな部分を忘れてしまいますよね。また、複数のプログラミング言語を習得している人は、頭がこんがりますね。

 そんな方におススメしたいのが、資格試験の問題を1日5問程度解いていく方法です。毎日のスキマ時間を活用して短時間で知識レベルを維持することが出来ますよ。Javaならば、Silverの問題集が最適です。
 Silverを既に取得している人も、これから取得を目指している人もぜひ試してみてください。

 さて、この記事では、タイトルの通り、C言語をテーマにしています。
問題を毎日5問投稿していきますので、C言語を習得中の方、C言語の知識を維持されたい方は、ぜひご活用ください。


■ ファイルの入出力

□ 1. 次のファイルにデータを書き込むプログラムの空欄に入るコードとして、正しいものを選びなさい。(1つ選択)

#include <stdio.h>

int main() {
    ____空欄____ = fopen("output.txt", "w");
    if (fp == NULL) {
        printf("ファイルが開けません\n");
        return 1;
    }

    fprintf(fp, "Hello, World!\n");
    fprintf(fp, "Welcome to C programming.\n");

    fclose(fp);
    return 0;
}

A.     FILE fp
B.   file *fp
C.   FILE *fp
D.   FILE &p


□ 2. 次のファイルにデータを書き込むプログラムの空欄に入るコードとして、正しいものを選びなさい。(1つ選択)

#include <stdio.h>

int main() {
    FILE *fp = fopen("sample.txt", "r");
    if (fp == NULL) {
        printf("ファイルが開けません\n");
        return 1;
    }

    char buffer[5];
    while (____ 空欄 ____) {
        printf("%s", buffer);
    }

    fclose(fp);
    return 0;
}

A.  fscanf(fp, "%s", buffer) != EOF
B.  fread(buffer, sizeof(char), 5, fp) > 0
C.  fgets(buffer, sizeof(buffer), fp) != NULL
D.  fread(buffer, sizeof(char), 5, fp) == 0


3. 次のファイル入出力に関する説明として、正しいものを選びなさい。(1つ選択)

A. fscanf 関数は、ファイルからフォーマットされたデータを読み取るために使用され、fwrite 関数と同様にバイナリデータも読み取れる。

B. fwrite 関数は、指定されたバッファからファイルにデータを書き込むため、テキストデータの書き込みにも適している。

C. fseek 関数は、ファイルポインタをファイルの終端に移動できるが、その位置から新たに書き込むとデータが上書きされる。

D. ftell 関数は、ファイルポインタが現在どの位置にあるかをバイト数で返す。


□ 4. 次のバイナリーファイルに出力するプログラムの空欄に入るコードとして、正しいものを選びなさい。(1つ選択)

#include <stdio.h>

int main() {
    FILE *fp = fopen("output.bin", "wb");
    float values[3] = {1.1, 2.2, 3.3};
    fwrite(____空欄____, sizeof(float), 3, fp);
    fclose(fp);
    return 0;
}

A.    values
B. *values
C. values[0]
D.   values[]


□ 5. 次のプログラムをコンパイルし、実行したときの出力結果として、正しいものを選びなさい。(1つ選択)

#include <stdio.h>

int main() {
    FILE *fp = fopen("numbers.bin", "wb");
    for (int i = 1; i <= 3; i++) {
        fwrite(&i, sizeof(int), 1, fp);
    }
    fclose(fp);

    fp = fopen("numbers.bin", "rb");
    int num;
    while (fread(&num, sizeof(int), 1, fp) == 1) {
        printf("%d ", num);
    }
    fclose(fp);
    return 0;
}

A.     1 2 3
B.  1 2 3 4
C.  0 1 2
D.  実行時にエラーが発生する


解答

1.C

fopen 関数は、指定されたファイルを開くために使用され、成功した場合にはファイルポインタへのポインタを返します。ファイルポインタは、ファイル操作に使用するため、ポインタ型である必要があります。そのため、FILE * 型の変数を定義してファイルを指し示します。

2.C

A. fscanf(fp, "%s", buffer) != EOF: fscanf は指定されたフォーマットに基づいてデータを読み取りますが、%s を使用する場合、空白文字で区切られた文字列を読み込みます。この場合、ファイルの終端を確認するためには、リターン値が1以上である必要があります(成功した読み取りの数)。したがって、!= EOF だけでは不十分です。この選択肢は正しくありません。

B. fread(buffer, sizeof(char), 5, fp) > 0: fread はバイナリデータを読み込むための関数であり、通常はバイナリファイルを扱う際に使用します。また、fread の戻り値は実際に読み取った要素の数であり、文字列の終端がどうなるかは考慮されません。このため、通常のテキストファイルの読み込みには適していません。この選択肢も不正解です。

C. fgets(buffer, sizeof(buffer), fp) != NULL: fgets はファイルから1行を読み込むために使用され、改行文字までまたは指定したバッファのサイズまでの文字列を読み込みます。この関数は成功した場合にそのポインタを返し、読み込むデータがなかったり、エラーが発生した場合には NULL を返します。このため、!= NULL は有効な条件です。この選択肢が正解です。

D. fread(buffer, sizeof(char), 5, fp) == 0: fread はバイナリデータを読み込むための関数ですが、この条件は、読み取った要素がゼロであるかどうかを確認するものです。ファイルの終端を確認する場合には、== 0 の条件は不適切です。この選択肢は不正解です。

3.D

A.
誤り: fscanf はフォーマットされたデータをテキストファイルから読み取るために使用されますが、バイナリデータを読み取ることには向いていません。バイナリデータを扱うには、fread を使用します。したがって、この説明は不正確です。

B.
誤り: fwrite 関数はバイナリデータを書き込むために設計されており、通常はテキストデータを扱う際には fprintf を使用します。テキストデータを書く場合に fwrite を使うこともできますが、テキストファイルとして適切に書き込まれない場合があります。この選択肢は正しくありません。

C.
誤り: fseek はファイルポインタを指定した位置に移動させる関数ですが、ファイルの終端に移動しても、上書きが発生するかどうかは、ファイルがどのモードで開かれているかによります。通常、"w" モードで開いた場合は上書きされますが、"a"(追記)モードで開いた場合は、終端に追加されます。このため、この説明は不正確です。

D.
正しい: ftell 関数は、現在のファイルポインタの位置をバイト数で返す関数です。これにより、ファイルのどの位置にいるかを確認することができます。この選択肢が正解です。


4.A

空欄には、書き込むデータのメモリの先頭を指すポインタを渡す必要があります。
A. 
正解です。values は配列の先頭アドレス(ポインタ)を指しているため、fwrite に渡すのに適しています。配列の全データを書き込む際にはこの形が正しいです。
B. values
不正解です。*values は values[0]、つまり最初の要素 1.1 の値を指しますが、fwrite には配列全体のポインタを渡す必要があります。
C. 
不正解です。values[0] も 1.1 という具体的な値であり、配列の先頭要素の値を指すため、データ全体を書き込むためのポインタではありません。
D. 
不正解です。values[] という書き方は構文エラーです。配列全体のポインタを指すには単に values と書く必要があります。


5.A

このプログラムは、まず整数 1, 2, 3 をバイナリファイル numbers.bin に書き込み、次にそのファイルから整数を読み込んで出力するものです。

バイナリファイルへの書き込み:
ファイル numbers.bin を書き込みモード (wb) で開きます。
ループを使って、変数 i を 1 から 3 まで増加させながら、fwrite で各値をファイルに書き込みます。書き込みは整数 int 型のサイズ(sizeof(int))を使い、1つずつ書き込んでいます。
fwrite(&i, sizeof(int), 1, fp) の書き込み内容は、i のアドレスを渡しているため、整数 1, 2, 3 が順にバイナリファイルに書き込まれます。

バイナリファイルからの読み込み:
次に、ファイルを読み込みモード (rb) で開きます。
fread(&num, sizeof(int), 1, fp) を使って1つずつ整数を読み込み、ファイルが終わるまでループで num に読み込んだ値を printf で出力します。
読み込む内容は先ほど書き込んだ整数なので、出力される値は 1, 2, 3 です。



本日の学習内容

お疲れ様でした。
継続は力なりです。
明日も頑張りましょう!

この記事が気に入ったらサポートをしてみませんか?