構造体とポインタについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
taz
記事: 35
登録日時: 13年前
住所: 兵庫

構造体とポインタについて

#1

投稿記事 by taz » 13年前

こんばんは。質問があります。構造体とポインタについてです。以下コードを示します。

コード:

//読み込みファイル
#include <stdio.h>
#include <stdlib.h>

#define END_FILE 0 //ファイルの終端
#define MENU 0 //メニューの表示
#define ADDR 1 //新規レコードの追加
#define UPDATER 2 //更新
#define DELR 3 //削除
#define DISPR 4 //一覧表示
#define CANCEL 5 //キャンセル
#define END 5 //キャンセル
#define NO 2 //いいえ
#define ERROR -1 //エラーの時
#define NOERROR 0 //エラーじゃない時

FILE *fp; //ファイルポインタ
char *fname = "comma.csv"; //ファイル名
int ret = 0; //関数の返り値
int choice=0; //キーボード入力値格納変数
int i_num=0; //構造体配列の番号

//会員メンバ構造体
struct member 
{
	int no;
	char name;
	char adress;
	char tel;
	char mail;
	struct member *pmember;
};

/*メイン関数*/
main()
{
	int Pno = 0;
	Pno = init_disp();
		while(Pno!=CANCEL)
		{
			switch(Pno)
			{
			case MENU:
				Pno = init_disp();
				break;
			/*case ADDR:
				Pno = add_record();
				break;*/
			/*case UPDATER:
				Pno = update_record();
				break;
			case DELR:
				Pno = del_record();
				break;*/
			case DISPR:
				Pno = disp_record();
				break;
			case END:
				break;
			}
		}
}

int init_disp()
{
	int no = 0; //数字の入力値
		
	printf("---会員管理システムメニュー---\n\n");
	printf("1.新規登録\n");
	printf("2.変更\n");
	printf("3.削除\n");
	printf("4.一覧表示\n");
	printf("5.終了\n");
	printf("No? ");
	scanf("%d",&no); //数値を入力
	
	return no;
}

//*一覧表示*/
int disp_record()
{
	struct member a, *ppmember;
	ppmember = &a;
	ret = csv_read(); //ファイルの読み出し関数
    
    //ファイル読み込み終了まで繰り返す
    while(feof(fp)==END_FILE)
    {
        //ファイルからデータを読み込み、構造体配列に格納
        if((fscanf(fp,"%d,%[^,],%[^,],%[^,],%s",ppmember->no,ppmember->name,ppmember->adress,ppmember->tel,ppmember->mail)) != EOF)
        {
               printf("\n%d",ppmember->no); //番号
               printf("\n%s",ppmember->name); //名前
               printf("\n%s",ppmember->adress); //住所
               printf("\n%s",ppmember->tel); //電話番号
               printf("\n%s",ppmember->mail); //メールアドレス
        }
    }
    printf("\n\n%s\n","メニューに戻ります。1:yes");
    scanf("%d",&choice); //メニューに戻るための入力
    //入力値が1の場合
    if(choice==1)
    {
        system("cls"); //コマンドプロンプトの表示クリア
        return MENU; //メイン関数に戻る
    }
    fclose(fp); //ファイルを閉じる
    return NOERROR;
}

int csv_read()
{
	fp = fopen(fname,"r"); //ファイルを読み込みモードで開く
	
	//ファイルポインタがNULLかどうか判定
	if(fp == NULL)
	{
		printf("%sファイルが開けません\n",fname);
		return ERROR; //エラーの返り値として-1を返す
	}
	return NOERROR;
}
上記91行目、
//ファイルからデータを読み込み、構造体配列に格納
if((fscanf(fp,"%d,%[^,],%[^,],%[^,],%s",ppmember->no,ppmember->name,ppmember->adress,ppmember->tel,ppmember->mail)) != EOF)
の部分でエラーが出ます。構造体のメンバに、不正な値が代入されているようです。
何が、問題なのか理解が出来ません。どなたかアドバイスよろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 構造体とポインタについて

#2

投稿記事 by みけCAT » 13年前

scanfの使い方はわかりますか?
ポインタを渡すべきところで値を渡しているようです。
fscanfはファイルポインタ以外scanfと同じです。
わからないようでしたら苦Cをどうぞ。
http://9cguide.appspot.com/06-01.html#S2
http://9cguide.appspot.com/15-03.html
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 15年前

Re: 構造体とポインタについて

#3

投稿記事 by box » 13年前

taz さんが書きました:

コード:

//*一覧表示*/
int disp_record()
{
	struct member a, *ppmember;
	ppmember = &a;
変数aの役割は、何ですか?
taz さんが書きました:

コード:

        //ファイルからデータを読み込み、構造体配列に格納
        if((fscanf(fp,"%d,%[^,],%[^,],%[^,],%s",ppmember->no,ppmember->name,ppmember->adress,ppmember->tel,ppmember->mail)) != EOF)
構造体の配列に相当する領域は、どこにありますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 構造体とポインタについて

#4

投稿記事 by softya(ソフト屋) » 13年前

前回の後でコメントしたんですが読んでもらってますか?
「putchar について • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=11095
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taz
記事: 35
登録日時: 13年前
住所: 兵庫

Re: 構造体とポインタについて

#5

投稿記事 by taz » 13年前

softya(ソフト屋) さんが書きました:前回の後でコメントしたんですが読んでもらってますか?
「putchar について • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=11095
読ませて頂きました。ありがとうございます。おかげで理解する事が出来ました。

taz
記事: 35
登録日時: 13年前
住所: 兵庫

Re: 構造体とポインタについて

#6

投稿記事 by taz » 13年前

コード:

//読み込みファイル
#include <stdio.h>
#include <stdlib.h>

#define END_FILE 0 //ファイルの終端
#define MENU 0 //メニューの表示
#define ADDR 1 //新規レコードの追加
#define UPDATER 2 //更新
#define DELR 3 //削除
#define DISPR 4 //一覧表示
#define CANCEL 5 //キャンセル
#define END 5 //キャンセル
#define NO 2 //いいえ
#define ERROR -1 //エラーの時
#define NOERROR 0 //エラーじゃない時

FILE *fp; //ファイルポインタ
char *fname = "comma.csv"; //ファイル名
int ret = 0; //関数の返り値
int choice=0; //キーボード入力値格納変数
int i_num=0; //構造体配列の番号

//会員メンバ構造体
struct member 
{
	int no;
	char name[20];
	char adress[20];
	char tel[20];
	char mail[20];
	struct member *pmember;
};

/*メイン関数*/
main()
{
	int Pno = 0;
	Pno = init_disp();
		while(Pno!=CANCEL)
		{
			switch(Pno)
			{
			case MENU:
				Pno = init_disp();
				break;
			/*case ADDR:
				Pno = add_record();
				break;*/
			/*case UPDATER:
				Pno = update_record();
				break;
			case DELR:
				Pno = del_record();
				break;*/
			case DISPR:
				Pno = disp_record();
				break;
			case END:
				break;
			}
		}
}

int init_disp()
{
	int no = 0; //数字の入力値
		
	printf("---会員管理システムメニュー---\n\n");
	printf("1.新規登録\n");
	printf("2.変更\n");
	printf("3.削除\n");
	printf("4.一覧表示\n");
	printf("5.終了\n");
	printf("No? ");
	scanf("%d",&no); //数値を入力
	
	return no;
}

//*一覧表示*/
int disp_record()
{
	struct member a, *ppmember;
	ppmember = &a;
	ret = csv_read(); //ファイルの読み出し関数
    
    //ファイル読み込み終了まで繰り返す
    while(feof(fp)==END_FILE)
    {
        //ファイルからデータを読み込み、構造体配列に格納
        if((fscanf(fp,"%d,%[^,],%[^,],%[^,],%s",&(ppmember->no),&(ppmember->name[0]),&(ppmember->adress[0]),&(ppmember->tel[0]),&(ppmember->mail[0]))) != EOF)
        {
               printf("\n%d",ppmember->no); //番号
               printf("\n%s",ppmember->name); //名前
               printf("\n%s",ppmember->adress); //住所
               printf("\n%s",ppmember->tel); //電話番号
               printf("\n%s",ppmember->mail); //メールアドレス
        }
    }
    printf("\n\n%s\n","メニューに戻ります。1:yes");
    scanf("%d",&choice); //メニューに戻るための入力
    //入力値が1の場合
    if(choice==1)
    {
        system("cls"); //コマンドプロンプトの表示クリア
        return MENU; //メイン関数に戻る
    }
    fclose(fp); //ファイルを閉じる
    return NOERROR;
}

int csv_read()
{
	fp = fopen(fname,"r"); //ファイルを読み込みモードで開く
	
	//ファイルポインタがNULLかどうか判定
	if(fp == NULL)
	{
		printf("%sファイルが開けません\n",fname);
		return ERROR; //エラーの返り値として-1を返す
	}
	return NOERROR;
}

以上のように、char型は文字列なので、配列にし、また呼び出す時に、配列の最初を指定する事で解決する事が出来ました。
アドバイスありがとうございました。

box
記事: 2002
登録日時: 15年前

Re: 構造体とポインタについて

#7

投稿記事 by box » 13年前

解決したとのことですが、今のdisp_record関数は
「単に出力しているだけ」で、出力したデータはこの関数を抜けた後、
どこにも残っていないことを理解しておいてください。
他の機能を実現しようとすると、その時点で大変お困りになるような気がします。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

taz
記事: 35
登録日時: 13年前
住所: 兵庫

Re: 構造体とポインタについて

#8

投稿記事 by taz » 13年前

box さんが書きました:解決したとのことですが、今のdisp_record関数は
「単に出力しているだけ」で、出力したデータはこの関数を抜けた後、
どこにも残っていないことを理解しておいてください。
他の機能を実現しようとすると、その時点で大変お困りになるような気がします。
アドバイスありがとうございます。他の機能についても、色々と試行錯誤して頑張りたいと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る