1時間ごとに更新!Amazon.co.jpで今売れている本トップ100   掲示板ランキング



掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.5580

どうやって繋いだらいいのかがわかりません?
投稿者---ザリガニです(2006/03/23 11:15:36)


ファイルの中のデータを読み込んでリスト構造に追加したいのですが
どうやったらいいのかわからなくなってしまいました。
周りに聞いてもnyuuryoku()の時と一緒だといわれるのですがどう一緒なのかわかりません教えてください。お願いします。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct MEMBER {
    int  ID;
    char Name[32];
    int  Age;
    struct MEMBER *next;
};

struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head);
void itiranhyou(struct MEMBER *head);
struct MEMBER *sakujo(struct MEMBER *head, struct MEMBER *fin);
void all_re(struct MEMBER *fin,struct MEMBER *head);

int main(void) {
    int w = 0;
    struct MEMBER dmy;
    struct MEMBER *head = &dmy;
    struct MEMBER *fin;
    struct MEMBER *z;
    FILE *fp;

    head = &dmy;
    z = &dmy;
    head->next = NULL;
    fin = head;

    if((fp=fopen("MEMBER_file.txt","r"))==NULL){                         /*ファイルオープン*/
        printf("ファイルが開かない\n");
        }
    else
        for(z = head->next; z != NULL; z = z->next){
        fscanf(fp, "%d  %s  %d ", &z->ID, z->Name, &z->Age);
            z->next =NULL;
            fin->next = z;
            fin = z;
        }
            fclose(fp);
        
        while (1){
            printf("<メニュー>\n1:追加\n2:一覧\n3:削除\n99:END\n\nNO?\n");     /*表示*/
        scanf_s("%d", &w);
        if(w == 1){                               /*入力*/ 
            fin = nyuuryoku(fin,head);
        }
        else if(w == 2){                         /*一覧表表示*/
            itiranhyou(head);                 
        }
        else if(w == 3){                        /*削除*/
            fin = sakujo(head,fin);
        }
        else if(w == 99){

            if((fp=fopen("MEMBER_file.txt","w"))==NULL){
        printf("ファイルが開かない\n");
   }
            for(z = head->next; z != NULL; z = z->next){
                fprintf(fp, "%d  %s  %d \n", z->ID, z->Name, z->Age);
            }
            fclose(fp);
            all_re(head,fin);                 /*メモリ解放*/
            break;
        }
        }
}
/*メモリ解放*/
void all_re(struct MEMBER *fin, struct MEMBER *head){
            struct MEMBER *a;
            struct MEMBER *g;
            for(a = head->next; a != NULL; a = g){
                g = a->next;
                free(a);
            }
        }


/*データ入力*/
struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head){

    struct MEMBER *a;
    struct MEMBER *g;

    if((a = (struct MEMBER*)malloc(sizeof(struct MEMBER)))==NULL){       /*メモリの確保*/
            printf("確保失敗\n");
            return fin;
        }
            printf("ID?");
            scanf_s("%d", &a->ID);
       for(g = head->next; g!=NULL; g = g->next){
                if(g->ID == a->ID){
                free(a);
                return fin;
                }
            }
            printf("名前?");
            scanf_s("%s", a->Name,31);
            printf("年齢?");
            scanf_s("%d", &a->Age);
            
                a->next = NULL;
                fin->next = a;
                fin = a;
            
                return fin;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:どうやって繋いだらいいのかがわかりません? 5581 kz3 2006/03/23 13:53:17


No.5581

Re:どうやって繋いだらいいのかがわかりません?
投稿者---kz3(2006/03/23 13:53:17)


>ファイルの中のデータを読み込んでリスト構造に追加したいのですが
>どうやったらいいのかわからなくなってしまいました。
>周りに聞いてもnyuuryoku()の時と一緒だといわれるのですがどう一緒なのかわかりません教えてください。お願いします。

どこからデータがやってくるかが違うだけで、( キーボード、ファイル )
入ってきたデータをリストにつなぐ方法は同じだという事ですよ。

キーボードから入ってきたデータをリストにつなげる事はできるが、
ファイルから入ってきたデータをリストにつなげない、
となると問題なのはファイルの入出力の方なのではないでしょうか?

ところで・・・
head = &dmy; z = &dmy; head->next = NULL; fin = head; if((fp=fopen("MEMBER_file.txt","r"))==NULL){ /*ファイルオープン*/ printf("ファイルが開かない\n"); } else for(z = head->next; z != NULL; z = z->next){ fscanf(fp, "%d %s %d ", &z->ID, z->Name, &z->Age); z->next =NULL; fin->next = z; fin = z; } fclose(fp);
この部分がパっと見、気になったのですが・・・。 ザリガニさんは何か気になりませんか? それぞれの値をメモにとってコードを追っていけば分かると思います。



この投稿にコメントする

削除パスワード

No.5582

Re:どうやって繋いだらいいのかがわかりません?
投稿者---ザリガニです(2006/03/23 14:34:06)


for文がいらないですよねあってもこれじゃループしないですな。
何とかできたんですが、ファイルの終了検査のところが何回読んでも理解できないんです。誰か教えてください。これは最後にどうやって処理したらいいんですか?お願いします
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct MEMBER {
    int  ID;
    char Name[32];
    int  Age;
    struct MEMBER *next;
};

struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head);
void itiranhyou(struct MEMBER *head);
struct MEMBER *sakujo(struct MEMBER *head, struct MEMBER *fin);
void all_re(struct MEMBER *fin,struct MEMBER *head);

int main(void) {
    int w = 0;
    struct MEMBER dmy;
    struct MEMBER *head = &dmy;
    struct MEMBER *fin;
    struct MEMBER *z;
    FILE *fp;

    head = &dmy;
    //z = &dmy;
    head->next = NULL;
    fin = head;

        if((fp=fopen("MEMBER_file.txt","r"))==NULL){                         /*ファイルオープン*/
        printf("ファイルが開かない\n");
        }
        else{
        while(1){
         if((z = (struct MEMBER*)malloc(sizeof(struct MEMBER)))==NULL){       
            printf("確保失敗\n");
        }

        fscanf(fp, "%d  %s  %d ", &z->ID, z->Name, &z->Age);
      
        //
        break;
            z->next =NULL;
            fin->next = z;
            fin = z;
    }
            fclose(fp);
    }
        while (1){
            printf("<メニュー>\n1:追加\n2:一覧\n3:削除\n99:END\n\nNO?\n");     /*表示*/
        scanf_s("%d", &w);
        if(w == 1){                               /*入力*/ 
            fin = nyuuryoku(fin,head);
        }
        else if(w == 2){                         /*一覧表表示*/
            itiranhyou(head);                 
        }
        else if(w == 3){                        /*削除*/
            fin = sakujo(head,fin);
        }
        else if(w == 99){

            if((fp=fopen("MEMBER_file.txt","w"))==NULL){
        printf("ファイルが開かない\n");
   }
            for(z = head->next; z != NULL; z = z->next){
                fprintf(fp, "%d  %s  %d \n", z->ID, z->Name, z->Age);
            }
            fclose(fp);
            all_re(head,fin);                 /*メモリ解放*/
            break;
        }
        }
}
struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head){

    struct MEMBER *a;
    struct MEMBER *g;

    if((a = (struct MEMBER*)malloc(sizeof(struct MEMBER)))==NULL){       /*メモリの確保*/
            printf("確保失敗\n");
            return fin;
        }
            printf("ID?");
            scanf_s("%d", &a->ID);
       for(g = head->next; g!=NULL; g = g->next){
                if(g->ID == a->ID){
                free(a);
                return fin;
                }
            }
            printf("名前?");
            scanf_s("%s", a->Name,31);
            printf("年齢?");
            scanf_s("%d", &a->Age);
            
                a->next = NULL;
                fin->next = a;
                fin = a;
            
                return fin;
}




この投稿にコメントする

削除パスワード

No.5583

Re:どうやって繋いだらいいのかがわかりません?
投稿者---near(2006/03/24 15:37:41)


>ファイルの終了検査のところが何回読んでも理解できないんです。
どこの事ですか?

以下気になったところ。

while(1)
{
    z = (struct MEMBER*)malloc(sizeof(struct MEMBER));
    if(z == NULL)
    {
        printf("確保失敗\n");
    }
    // ファイル一回しか読みませんよ
    fscanf(fp, "%d  %s  %d ", &z->ID, z->Name, &z->Age);
    break;
    
    z->next =NULL; // 実行されません
    fin->next = z; // 実行されません
    fin = z; // 実行されません
}


fp = fopen("MEMBER_file.txt","w"); if(fp == NULL) { printf("ファイルが開かない\n"); } for(z = head->next; z != NULL; z = z->next) { // ファイルが開けなくても実行されます fprintf(fp, "%d %s %d \n", z->ID, z->Name, z->Age); } fclose(fp);



この投稿にコメントする

削除パスワード

No.5584

Re:どうやって繋いだらいいのかがわかりません?
投稿者---kz3(2006/03/25 12:47:00)


>>ファイルの終了検査のところが何回読んでも理解できないんです。
>どこの事ですか?

>以下気になったところ。

ファイル入出力の前に基本文法から勉強し直したほうがいいかもですね。=>第6章 制御構造

+ 起動時のリストはです
|
+ ファイルオープン
|
+ ファイル終端までデータを一つずつ読み込む
| |
| + セルを一つ確保してリストに連結する
|
+ ファイルクローズ
|
x リストの構築終了

ざっとこんな流れになります。( なんていう図だ )

main()関数内にそのまま組み込まないで、
リストの初期化関数でも用意してみてがどうですか?
( 課題って勝手に付け足しちゃいけないんだろうか )



この投稿にコメントする

削除パスワード

No.5585

Re:どうやって繋いだらいいのかがわかりません?
投稿者---ザリガニです(2006/03/27 15:18:35)


もう一度振り返りながらやったところできました。
皆さんには感謝しています。申し訳ないのは十分承知しています。
バブルソートがまったく理解できません。バブルソートの動きは理解できました。課題で「バブルソートを使ってメモリ上のデータを名前の小さい順にソートして表示する」というのが出ました。教えていただけませんか。ヒントをいただけたいのですが、よろしくお願いします。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct MEMBER {
    int  ID;
    char Name[32];
    int  Age;
    struct MEMBER *next;
};

struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head);
void itiranhyou(struct MEMBER *head);
struct MEMBER *sakujo(struct MEMBER *head, struct MEMBER *fin);
void all_re(struct MEMBER *fin,struct MEMBER *head);

int main(void){
    int w = 0;
    struct MEMBER dmy;
    struct MEMBER *head = &dmy;
    struct MEMBER *fin;
    struct MEMBER *z;
    FILE *fp;
    int j; 

    head = &dmy;
    //z = &dmy;
    head->next = NULL;
    fin = head;

if((fp=fopen("MEMBER_file.txt","r"))==NULL){                         /*ファイルオープン*/
        printf("ファイルが開かない\n");
        }
        else{
            while(1){
if((z = (struct MEMBER*)malloc(sizeof(struct MEMBER)))==NULL){       
                printf("確保失敗\n");
            }
if(j=fscanf(fp, "%d  %s  %d ", &z->ID, z->Name, &z->Age) == EOF){
                free(z);
                break;}
            z->next =NULL;
            fin->next = z;
            fin = z;
         }
            fclose(fp);
            }
        while (1){
            printf("<メニュー>\n1:追加\n2:一覧\n3:削除\n5名前でソート\n99:END\n\nNO?\n");     /*表示*/
        scanf_s("%d", &w);
        if(w == 1){                               /*入力*/ 
            fin = nyuuryoku(fin,head);
        }
        else if(w == 2){                         /*一覧表表示*/
            itiranhyou(head);                 
        }
        else if(w == 3){                        /*削除*/
            fin = sakujo(head,fin);
        }
        
        else if(w == 99){

            if((fp=fopen("MEMBER_file.txt","w"))==NULL){
        printf("ファイルが開かない\n");
   }
            for(z = head->next; z != NULL; z = z->next){
                fprintf(fp, "%d  %s  %d \n", z->ID, z->Name, z->Age);
            }
            fclose(fp);
            all_re(head,fin);                 /*メモリ解放*/
            break;
        }
        }
}
/*メモリ解放*/
void all_re(struct MEMBER *fin, struct MEMBER *head){
            struct MEMBER *a;
            struct MEMBER *g;
            for(a = head->next; a != NULL; a = g){
                g = a->next;
                free(a);
            }
        }
/*データ入力*/
struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head){

    struct MEMBER *a;
    struct MEMBER *g;

    if((a = (struct MEMBER*)malloc(sizeof(struct MEMBER)))==NULL){       /*メモリの確保*/
            printf("確保失敗\n");
            return fin;
        }
            printf("ID?");
            scanf_s("%d", &a->ID);
       for(g = head->next; g!=NULL; g = g->next){
                if(g->ID == a->ID){
                free(a);
                return fin;
                }
            }
            printf("名前?");
            scanf_s("%s", a->Name,31);
            printf("年齢?");
            scanf_s("%d", &a->Age);
            
                a->next = NULL;
                fin->next = a;
                fin = a;
            
                return fin;
}
/*一覧表示*/
void itiranhyou(struct MEMBER *head){

    struct MEMBER *c;

    printf("ID     名前     年齢\n");
    for(c = head->next; c!=NULL; c = c->next) {
          printf("%d     %s     %d\n", c->ID, c->Name, c->Age);
    }
}
/*削除*/
struct MEMBER *sakujo(struct MEMBER *head, struct MEMBER *fin){
    struct MEMBER *k;
    struct MEMBER *l;
    int m = 0;

    printf("ID?\n");
    scanf_s("%d", &m);
    
    for(k = head; k->next !=NULL; k = k->next){
        if(k->next->ID == m){
            l = k->next;
            k->next = k->next->next;
            if(fin->ID == m){
                fin = k;
            }
                free(l);
                return fin;
            }
        }
    }



この投稿にコメントする

削除パスワード

No.5587

Re:どうやって繋いだらいいのかがわかりません?
投稿者---RAPT(2006/03/27 23:39:07)


ヒントも何も、「何が分からないのか」がその文面だけでは分かりません。

バブルソートがまったく理解できません。バブルソートの動きは理解できました。
さっぱり分かりません。 バブルソートのアルゴリズムが分からないのなら、ソートについて 調べれば良いです。 この場合、入出力とか、構造体とか、その辺は後回しにして、簡単な構造で 純粋にソート処理だけ考えた方が良いです。 例えば、下記のコードでバブルソート処理を実装してみてください。 #include <stdio.h> int main(void) { int values[] = { 1, 51, 42, 39, 24, 67, 44, 89, 31, 72, }; int i, count = sizeof(values) / sizeof(values[0]); printf("ソート前:\n"); for(i = 0; i < count; ++i){ printf("%4d", values[i]); } // バブルソート処理 printf("\n\nソート後:\n"); for(i = 0; i < count; ++i){ printf("%4d", values[i]); } return 0; }



この投稿にコメントする

削除パスワード

No.5588

Re:どうやって繋いだらいいのかがわかりません?
投稿者---ザリガニです(2006/03/29 14:23:36)


RAPTさん解けません。何から手をつけたらいいのかさえわかりません。
できなくてすみません。教えていただけませんか。
教えるのが面倒でしたら答えだけでもかまわないので教えてください。
答え見ながらやるだけやってみますのでお願いします。


この投稿にコメントする

削除パスワード

No.5589

Re:どうやって繋いだらいいのかがわかりません?
投稿者---ザリガニです(2006/03/29 14:52:58)


現在自分が添付したソースをといているんですが、どのように解くか理解してないんですが、自分なりにいろんな所を見ながらやってみました、
全然駄目でしょうが駄目だしお願いします.
新しい構造体を入れてもみました。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>



struct MEMBER {
int ID;
char Name[32];
int Age;
struct MEMBER *next;
};

struct member { /*ばぶるの構造体*/
int ID;
char Name[32];
int Age;
};

struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head);
void itiranhyou(struct MEMBER *head);
struct MEMBER *sakujo(struct MEMBER *head, struct MEMBER *fin);
void all_re(struct MEMBER *fin,struct MEMBER *head);
void BubbleSort(struct MEMBER *head);

int main(void){
int w = 0;
struct MEMBER dmy;
struct MEMBER *head = &dmy;
struct MEMBER *fin;
struct MEMBER *z;
FILE *fp;
int j;

head = &dmy;
//z = &dmy;
head->next = NULL;
fin = head;

if((fp=fopen("MEMBER_file.txt","r"))==NULL){ /*ファイルオープン*/
printf("ファイルが開かない\n");
}
else{
while(1){
if((z = (struct MEMBER*)malloc(sizeof(struct MEMBER)))==NULL){
printf("確保失敗\n");
}

if(j=fscanf(fp, "%d %s %d ", &z->ID, z->Name, &z->Age) == EOF){
free(z);
break;}
z->next =NULL;
fin->next = z;
fin = z;
}
fclose(fp);
}
while (1){
printf("<メニュー>\n1:追加\n2:一覧\n3:削除\n5名前でソート\n99:END\n\nNO?\n"); /*表示*/
scanf_s("%d", &w);
if(w == 1){ /*入力*/
fin = nyuuryoku(fin,head);
}
else if(w == 2){ /*一覧表表示*/
itiranhyou(head);
}
else if(w == 3){ /*削除*/
fin = sakujo(head,fin);
}
else if(w == 5){

}
else if(w == 99){

if((fp=fopen("MEMBER_file.txt","w"))==NULL){
printf("ファイルが開かない\n");
}
for(z = head->next; z != NULL; z = z->next){
fprintf(fp, "%d %s %d \n", z->ID, z->Name, z->Age);
}
fclose(fp);
all_re(head,fin); /*メモリ解放*/
break;
}
}
}
/*メモリ解放*/
void all_re(struct MEMBER *fin, struct MEMBER *head){
struct MEMBER *a;
struct MEMBER *g;
for(a = head->next; a != NULL; a = g){
g = a->next;
free(a);
}
}
/*データ入力*/
struct MEMBER *nyuuryoku(struct MEMBER *fin,struct MEMBER *head){

struct MEMBER *a;
struct MEMBER *g;

if((a = (struct MEMBER*)malloc(sizeof(struct MEMBER)))==NULL){ /*メモリの確保*/
printf("確保失敗\n");
return fin;
}
printf("ID?");
scanf_s("%d", &a->ID);
for(g = head->next; g!=NULL; g = g->next){
if(g->ID == a->ID){
free(a);
return fin;
}
}
printf("名前?");
scanf_s("%s", a->Name,31);
printf("年齢?");
scanf_s("%d", &a->Age);

a->next = NULL;
fin->next = a;
fin = a;

return fin;
}
/*一覧表示*/
void itiranhyou(struct MEMBER *head){

struct MEMBER *c;

printf("ID 名前 年齢\n");
for(c = head->next; c!=NULL; c = c->next) {
printf("%d %s %d\n", c->ID, c->Name, c->Age);
}
}
/*削除*/
struct MEMBER *sakujo(struct MEMBER *head, struct MEMBER *fin){
struct MEMBER *k;
struct MEMBER *l;
int m = 0;

printf("ID?\n");
scanf_s("%d", &m);

for(k = head; k->next !=NULL; k = k->next){
if(k->next->ID == m){
l = k->next;
k->next = k->next->next;
if(fin->ID == m){
fin = k;
}
free(l);
return fin;
}
}
}
/*ソート処理*/
void BubbleSort(struct MEMBER *head){
struct member swapbox;
struct member *v;
int i,j;
char Name [32];

for(x = 0; x < NULL; x++);
if((v=(struct member*)malloc(sizeof(struct member))*x)==NULL){
printf("確保失敗\n");}

for( i = 0 ; i < NULL ; i++ ){
for( j = i+1 ; j < NULL ; j++){
if(head[i].Name>head[j].Name) {
swapbox = Name[i];
Name[i] = Name[j];
Name[j] = swapbox;

}
}
}
}


この投稿にコメントする

削除パスワード

No.5590

Re:どうやって繋いだらいいのかがわかりません?
投稿者---Blue(2006/03/29 15:05:28)


まずは、どのようにして、並び替えるかを箇条書きにする。
それから、それにしたがってソースに起こします。

あなたは、考えもしていないようですが。
(小学生低学年でもトランプをランダムでくばって渡しも、
小さい順に並びかえれますよね?)

ということで、

1, 51, 42, 39, 24, 67, 44, 89, 31, 72

この数字をあなたならどのように並び替えますか?
まずは、日本語で箇条書きにしてみてください。
これができないようならば、あなたのためです、この道に進むことをあきらめたほうが良いです。
(仕事ならば、転職を考えてみてください。)


この投稿にコメントする

削除パスワード

No.5591

Re:どうやって繋いだらいいのかがわかりません?
投稿者---ザリガニです(2006/03/29 16:00:29)


どうもすみません。精一杯やっているんですが、わからないことだらけなんで迷惑かけます。仕事で使うために懸命にこれでもやっているんです。
勘弁してください。


この投稿にコメントする

削除パスワード

No.5592

Re:どうやって繋いだらいいのかがわかりません?
投稿者---Blue(2006/03/29 16:17:27)


Please refer.
http://myu.daa.jp/osiete/datsu.html


〜〜糸冬〜〜


この投稿にコメントする

削除パスワード

No.5593

Re:どうやって繋いだらいいのかがわかりません?
投稿者---REE(2006/03/29 16:27:09)


>どうもすみません。精一杯やっているんですが、わからないことだらけなんで迷惑かけます。仕事で使うために懸命にこれでもやっているんです。
>勘弁してください。

自分でプログラムを作れるようになりたいなら、結果だけを求めず、
まずはRAPTさんの問題を解いてみましょう。
リストのソートよりは楽なはずです。
これが出来ないなら、リストのソートも無理です。

そうでないのなら、上司or研修担当にその旨伝えましょう。



この投稿にコメントする

削除パスワード

No.5594

Re:どうやって繋いだらいいのかがわかりません?
投稿者---kz3(2006/03/29 18:25:46)


>どうもすみません。精一杯やっているんですが、わからないことだらけなんで迷惑かけます。仕事で使うために懸命にこれでもやっているんです。
>勘弁してください。

仕事って・・・業務プログラミングの事情は全くわかりませんが、
アルゴリズムの本とか置いてないんですか?
( もしくはザリガニさんが持っていないんですか? )

それともまだ研修中とか・・・。

どちらにしても、
アルゴリズムで大事なのは答えではなく考え方です。

>バブルソートがまったく理解できません。バブルソートの動きは理解できました。

動きを理解したのではなく、バブルソートで得られる結果を理解しただけ、の間違いではないですか?

バブルソートの考え方はこうです。

隣合う要素の順番が逆であれば位置を入れ替える作業をリストの端から一方の端まで、
ソート済み要素を除きながら全体を走査する。

ということは、どこまでソートが済んだか、ということを管理する必要があります。
# 管理しなくてもいいですが無駄な比較をするだけです
# 試しに配列の先頭から末尾に向かって隣同士の要素の並びを
# 適切に交換する作業を N-1 回繰り返すといいでしょう。

無駄に考えるより、WEBを探したらバブルソートのソースくらい
ゴロゴロしていると思うのですが・・・。



この投稿にコメントする

削除パスワード

No.5595

Re:どうやって繋いだらいいのかがわかりません?
投稿者---RiSK(2006/03/29 22:27:51)


感情的にならないでください。
ここは「技術系」の掲示板です。

>わからないことだらけ

「だらけ」をまずブレーンストームでリストにしてください。
その後,分からないなりにある程度まとめます。
そして,まとめたリストの一項目ずつ質問してください。

上記の課程を回答者にさせないでください。
# 物理的に無理だし。

>仕事で使うために

だったら,掲示板ではなくて上司に聞くべきだと思いますけど…。

>勘弁してください。

あなたの態度が良くない印象を与えてるのですけど…。


この投稿にコメントする

削除パスワード

No.5597

Re:どうやって繋いだらいいのかがわかりません?
投稿者---ねこやろう(2006/03/30 12:15:20)


んにゃ。暇だったから字下げしといた。
ソート関数はコンパイラ通らないから外したね。

#コメントに間違いがあったら誰か指摘してほしいナリ。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ↓VC++ 6.0 でコンパイル通す為
#define scanf_s scanf

// 保存ファイル名
#define MEMBER_FILE "MEMBER_file.txt"

#define MAX_NAME    32  // 名前の最大サイズ
struct MEMBER {
    int  ID;                // ID
    char Name[MAX_NAME];    // 名前
    int  Age;            // 年齢
    struct MEMBER *next;    // 次レコードアドレス
};
typedef struct MEMBER Member;

// 各関数宣言
Member* nyuuryoku(Member*, Member*); // データ入力処理
Member* sakujo(Member*, Member*);        // データ削除処理
void    itiranhyou(Member*);            // 一覧表示処理
void    all_re(Member*, Member*);      // 全メモリ解放処理


/****************
 *  メイン関数  *
 ****************/
int main(void)
{
    int j;
    int w = 0;
    Member dmy;
    Member *head = &dmy;
    Member *fin;
    Member *z;
    FILE *fp;

    head = &dmy;
    head->next = NULL;
    fin = head;

    // MEMBER_FILE(=MEMBER_file.txt)を開き前回データを読込む
    // MEMBER_FILEがない場合前回データはないものとする
    //   ->関数化すべき
    if ((fp = fopen(MEMBER_FILE, "r")) == NULL) {
        printf("ファイルが開かない\n");
    } else {
        while (1) {
            // 1レコード分領域を確保(先取り)
            if ((z = (Member*)malloc(sizeof(Member))) == NULL) {
                // 領域の確保に失敗した
                //   ->領域が確保できないのだから、そのまま処理を続けてはいけない
                printf("確保失敗\n");
            }

            // 1レコードづつ読込み、確保した領域に値を設定する(デリミタは空白)
            // レコードに空白(山田 太郎など)が入っていた場合誤動作するが無視(仕様?)
            if (j = fscanf(fp, "%d %s %d ", &z->ID, z->Name, &z->Age) == EOF) {
                // ファイルの終端に達したのでループを抜ける
                free(z);    // (先取りした)最後の領域は必要ないので解放
                break;
            }
            z->next = NULL; // リストの終端を意味するように次のアドレスをNULL設定
            fin->next = z;  // 一つ前のレコードと今回のレコードをつなげる
            fin = z;        // アドレスを退避して次のレコード読込みへ
                            // また最終的にfinがリストの最終レコードアドレスとなる
        }
        fclose(fp);
    }

    // メインメニュー
    while (1) {
        // 終了(=99)が選択されるまで繰返し
        //   ->system("clear")などにより画面更新をすると見易くなる
        printf("<メニュー>\n  1:追加\n  2:一覧\n  3:削除\n  5名前でソート\n  99:END\n\nNO? -->");
        scanf_s("%d", &w);
        if (w == 1) {         // データ追加
            fin = nyuuryoku(fin, head);

        } else if (w == 2) {    // 一覧表示
            itiranhyou(head);
            
        } else if (w == 3) {    // データ削除
            fin = sakujo(head, fin);
        
        } else if (w == 5) {    // データソート(未実装)
    
        } else if (w == 99) {   // 終了
            // レコードをファイル保存して終了
            //   ->関数化すべき
            if ((fp = fopen(MEMBER_FILE, "w")) == NULL) {
                // ファイルオープンエラー
                //   ->ファイルが開かないのだから処理を続けるべきではない
                printf("ファイルが開かない\n");
            }
            // 全レコード書込み(空白区切り)
            // headはダミー 実際のレコードはhead->nextから始まる
            // したがって、初期値にhead->next、次レコードzにz->nextを設定してデータを走査する
            // z = z->next == NULL は終端の為処理しないので全レコードを走査できる
            for(z = head->next; z != NULL; z = z->next) {
                // デリミタを空白としてファイル書込み
                fprintf(fp, "%d %s %d \n", z->ID, z->Name, z->Age);
            }
            fclose(fp);

            // 全メモリを解放して処理を終了
            all_re(head, fin);
            break;
        }
    }

    return 0;   // 正常終了
}

続きあるよ。


この投稿にコメントする

削除パスワード

No.5598

Re:どうやって繋いだらいいのかがわかりません?
投稿者---ねこやろう(2006/03/30 12:15:51)


続きね。

/**************************************************************
 * [メモリ解放処理]                                           *
 *   引数 : head = リストの先頭レコードアドレス               *
 *          fin  = リストの最終レコードアドレス ->不用        *
 *   戻値 : なし                                              *
 *   注意 : headはダミー 実際のレコードはhead->nextから始まる *
 **************************************************************/
void all_re(Member* fin, Member* head)
{
    Member *a;
    Member *g;

    // 全メモリ解放
    // 走査方法は基本的にデータ保存処理と同様
    for (a = head->next; a != NULL; a = g) {
        g = a->next;    // 解放前に次レコードアドレスを退避しておく
        free(a);
    }
}

/**************************************************************
 * [データ入力処理]                                           *
 *   引数 : head = リストの先頭レコードアドレス               *
 *          fin  = リストの最終レコードアドレス               *
 *   戻値 : リストの最終レコードアドレス                      *
 *   注意 : headはダミー 実際のレコードはhead->nextから始まる *
 **************************************************************/
Member* nyuuryoku(Member* fin, Member* head)
{
    Member *a;
    Member *g;

    // メモリ確保(先取り)
    if ((a = (Member*)malloc(sizeof(Member))) == NULL) {
        // メモリ確保失敗の為終了
        //   ->異常終了の為、呼出し元で処理できるようにすべき(引数・戻値の考慮要)
        printf("確保失敗\n");
        return fin;
    }

    printf("ID? -->");
    scanf_s("%d", &a->ID);
    // 重複IDがないかリストを検索する
    for (g = head->next; g != NULL; g = g->next) {
        if (g->ID == a->ID) {
            // 重複IDが存在するので処理を先取りしたメモリを解放して終了
            //   ->いきなりメニューに戻らずに、メッセージを表示するか、
            //     または更新処理に移行するなどすべき
            free(a);
            return fin;
        }
    }
    printf("名前? -->");
    scanf_s("%s", a->Name, 31);
    printf("年齢? -->");
    scanf_s("%d", &a->Age);

    // リストつなぎかえ
    a->next = NULL; // 今回登録したレコードが最後になるのでnextにNULLを設定
    fin->next = a;  // 今回登録したレコードをリストに追加
    fin = a;        // 最終レコードアドレスを今回登録レコードに更新

    return fin;
}

/**************************************************************
 * [一覧表示処理]                                             *
 *   引数 : head = リストの先頭レコードアドレス               *
 *   戻値 : なし                                              *
 *   注意 : headはダミー 実際のレコードはhead->nextから始まる *
 **************************************************************/
void itiranhyou(Member* head)
{
    Member *c;

    // 全レコード表示
    //   ->system("clear")などにより画面更新をすると見易くなる
    //     また、書式指定子により整形すると見易くなる
    printf("ID 名前 年齢\n");   // タイトル行
    for (c = head->next; c!=NULL; c = c->next) {
        printf("%d %s %d\n", c->ID, c->Name, c->Age);
    }
}

/**************************************************************
 * [データ削除処理]                                           *
 *   引数 : head = リストの先頭レコードアドレス               *
 *          fin  = リストの最終レコードアドレス               *
 *   戻値 : リストの最終レコードアドレス                      *
 *   注意 : headはダミー 実際のレコードはhead->nextから始まる *
 **************************************************************/
Member* sakujo(Member* head, Member* fin)
{
    int m = 0;
    Member *k;
    Member *l;

    printf("ID? -->");
    scanf_s("%d", &m);
    // 指定されたIDをリストより検索し、該当レコードを削除する
    for (k = head; k->next !=NULL; k = k->next) {
        if (k->next->ID == m) {
            // 削除レコードをリストから外す
            l = k->next;    // 解放するアドレスを退避
            // 削除レコードをとばすようリストをつなぎかえる
            k->next = k->next->next;

            // 削除レコードがリストの最終の場合、一つ前のレコードが最終となる
            if (fin->ID == m) {
                fin = k;
            }
            free(l);    // 指定されたIDのレコード領域を開放
            return fin;
        }
    }

    // return が抜けている
    //   ->指定されたIDがリストにない場合が考慮されていない
    //   VC++ 6.0 warning C4715: 'sakujo' : 値を返さないコントロール パスがあります
}

/********** END OF FILE **********/




この投稿にコメントする

削除パスワード

No.5596

Re:どうやって繋いだらいいのかがわかりません?
投稿者---keigo(2006/03/29 23:57:33)


>RAPTさん解けません。何から手をつけたらいいのかさえわかりません。
>できなくてすみません。教えていただけませんか。
>教えるのが面倒でしたら答えだけでもかまわないので教えてください。
>答え見ながらやるだけやってみますのでお願いします。

答えだけならば
1 51 42 39 24 67 44 89 31 72
を小さい順に並び替えるとして、答えは
1 24 31 39 42 44 51 67 72 89
となります。
私は 計算式=ソース 答え=結果 だと思っています。

1度質問の仕方について指摘したと思いますが・・・
「理解しました」と「わかりません」だけでは何を理解したのか何がわからないのかがわからないのです。

ソースを載せられてますがそれは理解されているのでしょうか?
「○」が入力されたら「□」が出力されますという感じで動きの説明は
できますか?
ザリガニですさん自身が書かれたソースが理解できていないのならば
まずはご自身で書かれたソースを理解することから始めてみたらどうでしょう?


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧





掲示板提供:(有)リアル・インテグリティ