【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板2こちら


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

No.19233

freadとfwrite処理について
投稿者---Q児(2005/01/16 19:11:43)


2件目にデータを入力したときにファイルに出力した
ダミーノードのデータが消えてしまいます。
fopenのモードが悪いのでしょうか?
アドバイスのほどよろしくお願いいたします。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define END -1

struct node{
    long int bango;
    char name[20];
    char denwa[15];
    long int next;
}NODE;
struct node *head;
FILE *fpbin, *fpcsv;                /*FILE構造体(グローバル変数)*/
struct node *memalloc(void);
void file_list_insert(long int bango,struct node *);
void file_list_append(struct node*, char *);
int file_list_delete(long int bango);
void file_list_display(void);


void main(int argc, char **argv)
{
    struct node seiseki;
    int kubun;
    struct node  *p;
    int cnt;
    if (argc != 2){
        printf("コマンドライン引数に誤りがあります。\n");
        printf("Usage:a.out filename1 \n");
        exit(EXIT_FAILURE);
    }
    head = memalloc();
    head -> next = END;
    fpbin = fopen(argv[1],"w+b");
    fwrite(head, sizeof(struct node),1,fpbin);
    fclose(fpbin);
    
    while(printf("処理区分を入力してください(1:挿入 2:追加 3:削除 4:表示 5:処理終了(表示))→"),scanf("%d", &kubun)){
            switch(kubun){
                case 1:
                    printf("case1\n");
                
                
                
                case 2:
                    p = memalloc();
                    printf("追加するNo 名前 tel >");
                    scanf("%ld %s %s", &p -> bango, p -> name, p -> denwa);
                    file_list_append(p,argv[1]);
                    break;
                
                
                
                
                case 3:
                    printf("case1\n");
                
                
               
                    //file_list_display();
                
                default:
                        printf("default\n");
                        if((fpbin = fopen(argv[1],"rb")) == NULL){ 
                            printf("error\n");
                            exit(1);
                        }
                        fread(&seiseki,sizeof(struct node),1,fpbin);
                        printf("seiseki.next = %ld\n", seiseki.next);
                        while(fseek(fpbin, seiseki.next, SEEK_SET) != 0){
                            if(fread(&seiseki,sizeof(struct node),1,fpbin) != NULL)
                                    break;
                            printf("seiseki.bango = %ld seiseki.name = %s seiseki.denwa = %s seiseki.next = %ld\n",seiseki.bango, seiseki.name, seiseki.denwa, seiseki.next);
                                
                        }
                        
                        fclose(fpbin);
                    
            }
    }
    
}


struct node *memalloc(void)
{
    struct node *p;
    
    if ( (p = (struct node *)malloc(sizeof(struct node))) != NULL ){
        return p;
    }
    
    printf("メモリの動的割当に失敗しました。\n");
    exit (1);
    
    return p;
}

void file_list_append(struct node *p, char *filename)
{
    struct node seiseki;/*ファイルに格納されている構造体(レコード)*/
    long int position;
    int cnt = 0;
    fpbin = fopen(filename,"rb");
    position = ftell(fpbin);
    fread(&seiseki,sizeof(struct node),1,fpbin);
    while(seiseki.next != END){
        
        fseek(fpbin, seiseki.next, SEEK_SET);
        printf("seiseki.next = %ld\n", seiseki.next);
        position = ftell(fpbin);
        fread(&seiseki,sizeof(struct node),1,fpbin);
        cnt++;
        if(cnt == 2)
            exit(1);    
        printf("seiseki.name = %s\n", seiseki.name);
    }
    
    seiseki.next = ftell(fpbin);
    
    fclose(fpbin);
    fpbin = fopen(filename,"wb");
    fseek(fpbin,position,SEEK_SET);
    fwrite(&seiseki, sizeof(struct node),1,fpbin);
    fseek(fpbin,seiseki.next,SEEK_SET);
    p -> next = END;
    fwrite(p, sizeof(struct node),1,fpbin);
    
    fclose(fpbin);
    
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:freadとfwrite処理について 19243 RiSK 2005/01/16 22:44:44
<子記事> Re:freadとfwrite処理について 19266 Craft 2005/01/17 10:27:26


No.19243

Re:freadとfwrite処理について
投稿者---RiSK(2005/01/16 22:44:44)


>2件目にデータを入力したときにファイルに出力した
>ダミーノードのデータが消えてしまいます。

どのように「2件目にデータを入力」するのでしょうか?
もう少し具体的に再現の方法を教えてください。

>fopenのモードが悪いのでしょうか?

ファイルの扱いはどうするつもりでしょうか?
…そもそも何をするプログラムなのでしょうか?


VC6 では以下の警告が出ました。

> (72) : warning C4047: '!=' : 間接参照のレベルが 'unsigned int ' と 'void *' で異なっています。

fread は読取りに成功した要素の個数を返します。型は size_t です。
fscanf などとは違いますよ。NULL との比較は NG.

> (27) : warning C4101: 'cnt' : ローカル変数は 1 度も使われません。

使わないものは削除。


この投稿にコメントする

削除パスワード

No.19276

Re:freadとfwrite処理について
投稿者---Q児(2005/01/17 13:58:54)



>ファイルの扱いはどうするつもりでしょうか?
>…そもそも何をするプログラムなのでしょうか?
まずファイルに追加処理をした後に、まだ作成していませんが、番号順に挿入処理、表示・削除処理をしていこうと思っています。


この投稿にコメントする

削除パスワード

No.19266

Re:freadとfwrite処理について
投稿者---Craft(2005/01/17 10:27:26)


>2件目にデータを入力したときにファイルに出力した
>ダミーノードのデータが消えてしまいます。
>fopenのモードが悪いのでしょうか?
>アドバイスのほどよろしくお願いいたします。

>void file_list_append(struct node *p, char *filename)
ここの、
> cnt++;
> if(cnt == 2)
> exit(1);
これは何を意味しているのでしょう?2件でexitしている理由は?

BorlandC++Builderでコンパイルして、どんなことをしたいのかいろいろ修正してためしてみました。
上記カウンタを消した状態で3回この関数を呼ぶと、これを呼んだときにfreadが正常終了するのもかかわらず、データがとれない、ということまではわかりました。

もう少し情報がないと解決できないかもしれません。

file処理関数にエラー処理があったりなかったりしていますが、fopen,fread,fwrite,fseekはエラー判定したほうがいいですよ。


この投稿にコメントする

削除パスワード

No.19275

Re:freadとfwrite処理について
投稿者---Q児(2005/01/17 13:55:33)


>> cnt++;
>> if(cnt == 2)
>> exit(1);
>これは何を意味しているのでしょう?2件でexitしている理由は?
これはなぜ2回目にうまくいっていないのか、確認するために用いたものです。
fopen処理をしたときに前回入力したデータが消えてしまっています。なので1度目はダミーノードの値を書き込みますが、2度目にこの関数に入った場合はダミーノードを書き込まないのでうまくたどることができないしだいです。
関数を実行するときにはじめのデータを消去しない方法はありますか?
それとももう一度全て書き直さないといけないのでしょうか?


この投稿にコメントする

削除パスワード

No.19277

Re:freadとfwrite処理について
投稿者---あかま(2005/01/17 14:07:19)


>fopen処理をしたときに前回入力したデータが消えてしまっています。
プログラム読んでないけど、
fpbin = fopen(argv[1],"w+b");
で開いてるからでは?
追加書き込みは"a"ですよ。"w"で開くと全部消えます。


この投稿にコメントする

削除パスワード

No.19387

Re:freadとfwrite処理について
投稿者---Q児(2005/01/22 13:13:13)


関数ごとにfopen処理をやっていたのでややこしくなったみたいです。
main関数にfopenとfcloseをひとつずつあればよかったみたいで無駄なことしてたみたいです。そうしたらうまく処理ができました。



この投稿にコメントする

削除パスワード

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