C言語関係掲示板

過去ログ

No.273.構造体の書き込み、表示、検索

[戻る] [ホームページ]


No.1636

配列と構造体の使い方
投稿者---nakko(2002/06/01 10:22:40)


こんにちは、C言語を勉強中(まだ初心者)のnakkoです。お世話になります。
下記のような、メニューの番号を選んでもらい、それぞれファイルに書き込む、ファイルの内容を表示する、ファイルの内容を検索するというプログラムを作りたいのです。
なんとかファイルに書き込むのと、読み込んで表示するとこまでは作ったのですが、検索の作り方がわかりません。
同じDepartmentの人を抜き出し、表示する検索です。
配列を使うと思ったのですが、どこをどう変えればよいのやらまったくわかりません。
どなたか教えていただけますでしょうか?

#include<stdio.h>
#include<conio.h>

struct emp
{
char add[21],position[21],department[16];
int id;
long int salary;
};

void main()
{
FILE *employee;
int choice;
struct emp staff;
employee = fopen("info.DAT","a");
if(employee==0)
{
printf("An error\n");
exit(1);
}
do
{

printf("\n");
printf(" M E N U\n\n");
printf("1. Add a new staff\n");
printf("2. Get the staff of a department\n");
printf("3. List the details of all staff records\n");
printf("4. Exit program\n");
printf("\n");
printf("Please enter the menu number : ");
scanf("%d",&choice);

if(choice==1)
{
do
{
printf("\nPlease enter new staff name(up to 20 characters)\n");
printf("(Press q to finish this program)\n");
printf("Enter : "); scanf("%s",staff.add);

if(staff.add[0] !='q')
{
printf("Please enter ID number(up to 5 digits) :");
scanf("%d",&staff.id);

printf("Please enter Position(up to 20 characters) :");
scanf("%s",staff.position);

printf("Please enter Department(up to 15 digits) :");
scanf("%s",staff.department);

printf("Please enter Salary(up to 5 digits) :");
scanf("%ld",&staff.salary);

getchar();
fprintf(employee,"%d %s %s %s %ld\n",staff.id,staff.add,staff.position,staff.department,staff.salary);
}
}while(staff.add[0] !='q');
fclose(employee);
}

else if(choice==2)
{
  //ここに検索のプログラムを書きたいのです
}

else if(choice==3)
{
employee = fopen("info.DAT","r");

while(fscanf(employee,"%d %s %s %s %ld\n",&staff.id,staff.add,staff.position,staff.department,&staff.salary) !=EOF)
printf("%d %s %s %s %ld\n",staff.id,staff.add,staff.position,staff.department,staff.salary);
fclose(employee);
}
}while (choice!=4);
}


No.1637

Re:配列と構造体の使い方
投稿者---shelly(2002/06/01 13:20:21)


こんにちは。
#ソースはインデントをつけて。お願い・・・

新しくプログラムを組む時、何をどうしていいかわからない、
という状況は初心者によくあることだと思います。
まあ経験とともに解消される問題ですけどね。
とりあえず現段階でのアプローチ方法として、やりたいことを
日本語で羅列してみてはどうでしょう。
1.検索するdepartmentを入力
2.


(最後)検索にマッチしたものを表示する。
という風に。
そのひとつひとつをCのソースに直す方法を考えてみてはどうでしょう。
わからない部分がはっきりして、質問もそれに対するコメントも
ズバッとくるんじゃないかな。



No.1644

Re:配列と構造体の使い方
投稿者---かずま(2002/06/02 13:13:37)


> 下記のような、メニューの番号を選んでもらい、それぞれファイルに書き込む、ファイル
> の内容を表示する、ファイルの内容を検索するというプログラムを作りたいのです。

メニューの 1 を 2回実行しようとしても、1回目で fclose されるので、
2回目はデータを書き込めないようです。fopen の位置がおかしいようです。
main だけでプログラムを書くのではなく、関数を使って小さい単位で
処理を記述しましょう。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct emp {
    char add[21], position[21], department[16];
    int  id;
    long salary;
};

int get_data(FILE *fp, struct emp *p)
{
    return fscanf(fp, "%d %s %s %s %ld\n",
        &p->id, p->add, p->position, p->department, &p->salary) == 5;
}

void put_data(FILE *fp, const struct emp *p)
{
    fprintf(fp, "%d %s %s %s %ld\n",
        p->id, p->add, p->position, p->department, p->salary);
}

void add(void)
{
    struct emp staff;
    FILE *employee = fopen("info.DAT", "a");
    if (employee == NULL) return;

    for (;;) {
        printf("\nPlease enter new staff name(up to 20 characters)\n");
        printf("(Press q to finish this program)\n");
        printf("Enter : ");
        if (scanf("%20s", staff.add) != 1) exit(1);

        if (staff.add[0] == 'q')
            break;
        printf("Please enter ID number(up to 5 digits) :");
        if (scanf("%d", &staff.id) != 1) exit(1);

        printf("Please enter Position(up to 20 characters) :");
        if (scanf("%20s", staff.position) != 1) exit(1);

        printf("Please enter Department(up to 15 digits) :");
        if (scanf("%15s", staff.department) != 1) exit(1);

        printf("Please enter Salary(up to 5 digits) :");
        if (scanf("%5ld",&staff.salary) != 1) exit(1);

        put_data(employee, &staff);
    }
    fclose(employee);
}

void get(void)
{
    char department[16];
    struct emp staff;
    FILE *employee = fopen("info.DAT", "r");
    if (employee == NULL) return;

    printf("Please enter Department(up to 15 digits) :");
    if (scanf("%s", department) != 1) exit(1);
    while (get_data(employee, &staff))
        if (strcmp(staff.department, department) == 0)
            put_data(stdout, &staff);
    fclose(employee);
}

void list(void)
{
    struct emp staff;
    FILE *employee = fopen("info.DAT", "r");
    if (employee == NULL) return;

    while (get_data(employee, &staff))
        put_data(stdout, &staff);
    fclose(employee);
}

int main()
{
    int choice;

    for (;;) {
        printf("\n");
        printf(" M E N U\n\n");
        printf("1. Add a new staff\n");
        printf("2. Get the staff of a department\n");
        printf("3. List the details of all staff records\n");
        printf("4. Exit program\n");
        printf("\n");
        for (;;) {
            printf("Please enter the menu number : ");
            if (scanf("%d", &choice) == 1) break;
            scanf("%*[^\n]"); /* 改行文字の前まで読み飛ばす */
        }
        switch (choice) {
        case 1: add();  break;
        case 2: get();  break;
        case 3: list(); break;
        case 4: return 0;
        }
    }
}


No.1645

Re:配列と構造体の使い方
投稿者---nakko(2002/06/02 13:30:12)


プログラムを組む時のコツや、実際のソースをいただき、
とても勉強になりました。
関数の使い方がまだ苦手なので、そこももういちど勉強し直さないといけないなと思います。
またお世話になるかもしれませんが、その時はまたよろしくお願いします。