web-dev-qa-db-ja.com

Cでのバイナリファイルの読み取りと書き込み

これらは2つの個別のアプリケーションです。

  • 最初の例では、名前、年齢、給与などの従業員の詳細をemp.binというバイナリファイルに保存しようとしました。
  • 2番目のアプリケーションでは、ファイルの内容を表示しようとしましたが、名前の代わりに最初の文字しか表示されません。

各文字を個別に印刷してみましたが、名前の各文字の後に3つのヌル文字「\ n」があるため、最初の文字の後には印刷されません。

「書き込み」アプリケーションコード:

//Receives records from keyboard and writes them to a file in binary mode
#include <stdio.h>

int main()
{
    FILE *fp;
    char another = 'Y';
    struct emp
    {
        char name[40];
        int age;
        float bs;
    };
    struct emp e;
    fp = fopen("emp.bin", "wb");
    if (fp == NULL)
    {
        puts("Cannot open the file.");
        return 1;
    }
    while(another == 'Y')
    {
        printf("Enter the employee name, age and salary: ");
        scanf("%S %d %f", e.name, &e.age, &e.bs);
        while(getchar() != '\n');
        fwrite(&e, sizeof(e), 1, fp);
        printf("Add another record? (Y/N)");

        another = getchar();
    }
    fclose(fp);
    return 0;
}

「読み取り」アプリケーションコード:

//Read records from binary file and displays them on VDU
#include <stdio.h>
#include <ctype.h>

int main()
{
    FILE *fp;
    struct emp
    {
        char name[40];
        int age;
        float bs;
    } e;
    fp = fopen("emp.bin", "rb");
    if (fp == NULL)
    {
        puts("Cannot open the file.");
        return 1;
    }
    while (fread(&e, sizeof(e), 1, fp) == 1)
    {
        printf("\n%s \t %d \t $%.2f\n", e.name, e.age, e.bs);
    }
    fclose(fp);
}

入力と出力は次のとおりです。

enter image description hereenter image description here

このコードを修正して名前全体を印刷するにはどうすればよいですか?

7
0x5961736972

Robertoの回答で述べたように、問題は_%S_変換指定子であり、これはタイプミスです。_%s_を使用する必要があります。

ただし、問題を引き起こす可能性のある他の問題があることに注意してください。

  • scanf()に従業員名として読み取る最大文字数を指定する必要があります。そうしないと、入力が長すぎる場合、scanf()が宛先配列の終わりを超えて書き込む可能性があります。

  • 両方のプログラムがエンディアン方式が異なる別々のシステムで実行される場合、バイトは逆の順序で格納されるため、受信側での数値は正しくありません。このため、バイナリファイルではエンディアンを明示的に指定して処理する必要があります。データ送信にはテキスト形式が好まれる傾向があります。

ここに変更されたバージョンがあります:

_//Receives records from keyboard and writes them to a file in binary mode
#include <stdio.h>

int main() {
    FILE *fp;
    char another = 'Y';
    struct emp {
        char name[40];
        int age;
        float bs;
    } e;
    int c;

    fp = fopen("emp.bin", "wb");
    if (fp == NULL) {
        puts("Cannot open the file.");
        return 1;
    }
    while (another == 'Y') {
        printf("Enter the employee name, age and salary: ");
        if (scanf("%39s %d %f", e.name, &e.age, &e.bs) != 3)
            break;
        while ((c = getchar()) != EOF && c != '\n')
            continue;
        if (fwrite(&e, sizeof(e), 1, fp) != 1)
            break;
        printf("Add another record? (Y/N)");
        another = getchar();
    }
    fclose(fp);
    return 0;
}
_

「読み取り」アプリケーションコード:

_//Read records from binary file and displays them on VDU
#include <stdio.h>
#include <ctype.h>

int main() {
    FILE *fp;
    struct emp {
        char name[40];
        int age;
        float bs;
    } e;
    fp = fopen("emp.bin", "rb");
    if (fp == NULL) {
        puts("Cannot open the file.");
        return 1;
    }
    while (fread(&e, sizeof(e), 1, fp) == 1) {
        printf("\n%s \t %d \t $%.2f\n", e.name, e.age, e.bs);
    }
    fclose(fp);
    return 0;
}
_
0
chqrlie