掲示板利用宣言

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

 私は

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

掲示板2

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

No.26711

ファイルから情報を読み込み処理をするプログラムについて
投稿者---秋桜(2006/04/29 11:39:29)


初めて投稿します。線形リストを使って商品の仕入れなどの管理を行うプログラムを作っています。
ファイルから
add 1234 apple 50 3
sell 1234 2
print
といった内容を読み込みます。 ただしそれぞれ、
add 商品ID 名前 値段 個数 (商品の追加)
sell 商品ID 個数 (商品を売却)
print (現在の在庫状況を表示)
となっています。
また、リストは商品IDの小さな順に並べます。
上の結果は、
1234 apple 50円 1個
として別のファイルに出力されるプログラムを作ろうとしています。
そこで下のようにプログラムを作ったのですが、エラーや警告が出ないのに、実行すると強制終了となってしまいます。
これはなぜなのでしょう?
助言等、お願いできますでしょうか?

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

typedef struct goods{
int ID;
char name[10];
int price;
int number;
struct goods *next;
}kanri;
kanri *head;

int main(void){
FILE *fp1 ,*fp2;
kanri *p,*q;
char c[10];
if((fp1 = fopen("input.dat" ,"r"))==NULL){
exit(EXIT_FAILURE);
}
head->next = q;
while (fscanf(fp1,"%s",c) != EOF) {
q = (struct goods *) malloc(sizeof(struct goods));
p = (struct goods *) malloc(sizeof(struct goods));
if(strcmp(c,"add")==0){
fscanf(fp1,"%d %s %d %d", &p->ID, p->name, &p->price, &p->number);
q = head;
while((p->ID) > (q->ID)){
q = q->next;
}
p->next = q->next;
q->next = p;
}

if(strcmp(c,"sell")==0){
int i,n;
fscanf(fp1,"%d %d",&i,&n);
q = head;
while(i != q->ID){
q = q->next;
}
q->number = q->number - n;
}


else if(strcmp(c,"print")==0){
if((fp2 = fopen("output.dat","w"))==NULL){
exit(EXIT_FAILURE);
}
for(q=head; q !=NULL ; q=q->next){
fprintf( fp2 , "%d %s %d円 %d個",q->ID, q->name, q->price, q->number);
}
break;
}

}
fclose(fp1);
fclose(fp2);
free(p);
free(q);
return EXIT_SUCCESS;

}


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイルから情報を読み込み処理をするプログラムについて 26712 KING・王 2006/04/29 12:39:16
<子記事> Re:ファイルから情報を読み込み処理をするプログラムについて 26715 kz3 2006/04/30 09:32:54
<子記事> Re:ファイルから情報を読み込み処理をするプログラムについて 26726 秋桜 2006/05/02 18:37:27


No.26712

Re:ファイルから情報を読み込み処理をするプログラムについて
投稿者---KING・王(2006/04/29 12:39:16)


まず、デバッガなどを用いて、どこの部分で強制終了が発生するかかくにんしましょう。

おそらく、
> head->next = q;
で、headはポインタであり、それがさすメモリが確保されていないのが、
原因でしょう。



この投稿にコメントする

削除パスワード

No.26713

Re:ファイルから情報を読み込み処理をするプログラムについて
投稿者---秋桜(2006/04/30 01:04:01)


返信ありがとうございます。
headの領域を確保しましたが、再び強制終了となってしまいました。
デバッガをダウンロードして使ってみたのですが、使い方などがよく
分からず行き詰ってしまいました。。。
そこで、q->next=NULL;というものを加えてみたところ、強制終了はなくなりました。
しかしoutput.txtには何も出力されていない状態でした。
このほかに考えられる要因はありますでしょうか・・・?


この投稿にコメントする

削除パスワード

No.26714

Re:ファイルから情報を読み込み処理をするプログラムについて
投稿者---def(2006/04/30 05:13:23)


コメントや字下げがないと読みにくいのですが...
q->next=NULLで強制終了が無くなったならその辺が怪しいですね。
output.txtに何も入力されなくなったのは、入るべきはずのデータが入っていないのか、条件チェックでスルーされたのかわかりませんが、その辺を見直すと答えが出てくるかもしれません。
デバッグ用に「ソースコードのこの部分が実行されるとコンソールにメッセージを表示」みたいにして、実験すると以外と効果があったりします。


この投稿にコメントする

削除パスワード

No.26716

Re:ファイルから情報を読み込み処理をするプログラムについて
投稿者---KING・王(2006/04/30 09:40:21)


>デバッガをダウンロードして使ってみたのですが、使い方などがよく
>分からず行き詰ってしまいました。。。

デバッガが使えないのは、かなり致命的なので、なんとしても使い方を覚えましょう。
とりあえず、最初にながしていましたが、掲示板利用宣言の

> 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。

を守りましょう。
環境、特にコンパイラが分からなければ、デバッガの使い方の説明も誰もできません。

で、デバッガなしでのデバッグ方法を紹介しておきます。

#include<stdio.h>
〜省略〜

FILE *fpdebug = NULL;

int main(void){
FILE *fp1, *fp2;
kanri *p, *q;
char c[10];

    /* open debug log file */
    fpdebug = fopen( "DebugLog.txt", "a" );
    if( fpdebug == NULL ){
        /* degug log file open error */
        return -1;
    }

    fprintf( fpdebug, "STEP = 1\n" );
    if( ( fp1 = fopen( "input.dat", "r" ) ) = NULL ){
        fprintf( fpdebug, "STEP = 2\n" );
        exit( EXIT_FAILURE );
    }

    fprintf( fpdebug, "STEP = 3\n" );
    head->next = q;
    fprintf( fpdebug, "STEP = 4\n" );

〜省略〜


このような感じで、fprintf()でファイルにどの部分が実行されたかや、
場合によっては、fprintf()でその時点の変数の値等を出力すれば、
どのようにプログラムが実行されていたか見えたりします。


この投稿にコメントする

削除パスワード

No.26715

Re:ファイルから情報を読み込み処理をするプログラムについて
投稿者---kz3(2006/04/30 09:32:54)


とりあえず字下げですね。

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct goods{ int ID; char name[10]; int price; int number; struct goods *next; }kanri; kanri *head; int main(void){ FILE *fp1 ,*fp2; kanri *p,*q; char c[10]; if((fp1 = fopen("input.dat" ,"r"))==NULL){ exit(EXIT_FAILURE); } head->next = q; /* 既出 */ while (fscanf(fp1,"%s",c) != EOF) { q = (struct goods *) malloc(sizeof(struct goods)); /* 必要? */ p = (struct goods *) malloc(sizeof(struct goods)); if(strcmp(c,"add")==0){ fscanf(fp1,"%d %s %d %d", &p->ID, p->name, &p->price, &p->number); q = head; /* 問題あり */ while((p->ID) > (q->ID)){ q = q->next; /* 既出に依存( nextは不正なポインタかもしれない ) */ } p->next = q->next; q->next = p; } if(strcmp(c,"sell")==0){ int i,n; fscanf(fp1,"%d %d",&i,&n); q = head; while(i != q->ID){ q = q->next; } q->number = q->number - n; } else if(strcmp(c,"print")==0){ if((fp2 = fopen("output.dat","w"))==NULL){ exit(EXIT_FAILURE); } for(q=head; q !=NULL ; q=q->next){ fprintf( fp2 , "%d %s %d円 %d個",q->ID, q->name, q->price, q->number); } break; } } fclose(fp1); fclose(fp2); free(p); free(q); return EXIT_SUCCESS; }
>線形リストを使って商品の仕入れなどの管理を行うプログラムを作っています。 最初のコードから少し手直しされているようですが、上のコードについて、 リンクリストの基本的アルゴリズムがめちゃくちゃです... もっと単純なデータでリンクリストのテストをするのはどうですか? ( そんな時間は無いって? ) せっかく確保した領域を孤立させているところもあるので、このままではメモリリークの可能性もあります。 最後のfree()に関してもリスト全体を解放しないと意味がないですよ。 あとプログラムの機能をmain関数にそのままぶち込まないで、 処理単位で関数化するのはどうですか? 見やすくなるだけでなく、関数化すること自体が頭の整理にも繋がります。 現在のコードを「HTML変換ツール」で字下げして見せてもらったら、 また違ったアドバイスが出来ると思います。



この投稿にコメントする

削除パスワード

No.26726

Re:ファイルから情報を読み込み処理をするプログラムについて
投稿者---秋桜(2006/05/02 18:37:27)


返信が遅くなりすみません。
解決しました!
回答してくださった皆様、ありがとうございました!!


この投稿にコメントする

削除パスワード

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