ファイルから該当データの表示させたぃ・・
ファイルから該当データの表示させたぃ・・
はじめましてぇ♪
chii☆と申します(^○^)☆
ファイルから該当データだけを表示させたぃのですが、
どうすればぃぃでしょうかぁ??
例ぇば、
番号 : 1
名前 : tanaka taro
クラス : A
委員 : 美化
年齢 : 16
番号 : 2
名前 : yamada jiro
クラス : B
委員 : 体育
年齢 : 16
番号 : 3
名前 : tanaka haru
クラス : C
委員 : 保健
年齢 : 16
番号 : 4
名前 : yamamoto itiro
クラス : D
委員 : 図書
年齢 : 16
このようなa.txtというファイルがあったとして、
番号を入力すると該当データだけをファイルから読み込み
表示させたぃのですが、どうすればぃいでしょうか??
番号入力で”4 ”を入力すると
表示は、
番号 : 4
名前 : yamamoto itiro
クラス : D
委員 : 図書
年齢 : 16
このように表示させたいです。
よろしくお願ぃします!!!
chii☆と申します(^○^)☆
ファイルから該当データだけを表示させたぃのですが、
どうすればぃぃでしょうかぁ??
例ぇば、
番号 : 1
名前 : tanaka taro
クラス : A
委員 : 美化
年齢 : 16
番号 : 2
名前 : yamada jiro
クラス : B
委員 : 体育
年齢 : 16
番号 : 3
名前 : tanaka haru
クラス : C
委員 : 保健
年齢 : 16
番号 : 4
名前 : yamamoto itiro
クラス : D
委員 : 図書
年齢 : 16
このようなa.txtというファイルがあったとして、
番号を入力すると該当データだけをファイルから読み込み
表示させたぃのですが、どうすればぃいでしょうか??
番号入力で”4 ”を入力すると
表示は、
番号 : 4
名前 : yamamoto itiro
クラス : D
委員 : 図書
年齢 : 16
このように表示させたいです。
よろしくお願ぃします!!!
Re:ファイルから該当データの表示させたぃ・・
えぇと、chii☆さんが今の状態でどこまで出来ているのかわからないので、
今のままだと一から全部教える必要が出てきます。
1.a.txtを開く
2.a.txtを読み込む
3.読み込んだデータを構造体に入れる
4.表示したい番号を入力してもらう
5.構造体のデータから入力してもらった番号と同じものを探す
6.該当するものがあれば画面に出力する
こんな感じの流れになると思いますが、どこまで分かっていてどこでつまづいているんでしょうか?
それとも1つも分からないという状態でしょうか?
今のままだと一から全部教える必要が出てきます。
1.a.txtを開く
2.a.txtを読み込む
3.読み込んだデータを構造体に入れる
4.表示したい番号を入力してもらう
5.構造体のデータから入力してもらった番号と同じものを探す
6.該当するものがあれば画面に出力する
こんな感じの流れになると思いますが、どこまで分かっていてどこでつまづいているんでしょうか?
それとも1つも分からないという状態でしょうか?
Re:ファイルから該当データの表示させたぃ・・
返信ありがとうござぃます☆
そういう流れになるんですね。
今の状態は、
1.a.txtを開く
2.a.txtを読み込む
までしかわからないです。。
すぃませんが、ご指導宜しくお願ぃ致します!!
そういう流れになるんですね。
今の状態は、
1.a.txtを開く
2.a.txtを読み込む
までしかわからないです。。
すぃませんが、ご指導宜しくお願ぃ致します!!
Re:ファイルから該当データの表示させたぃ・・
まず、構造体の作り方はわかりますか?
文章の中から特定の文字列を発見する方法はわかりますか?
たとえば
char st[/url]="I like DX Library and DirectX.";
という文字列があった時、「DX」の次にある単語を配列に格納せよ
と言われたら出来ますか?
この両者が出来たら完成も間近です。
文章の中から特定の文字列を発見する方法はわかりますか?
たとえば
char st[/url]="I like DX Library and DirectX.";
という文字列があった時、「DX」の次にある単語を配列に格納せよ
と言われたら出来ますか?
この両者が出来たら完成も間近です。
Re:ファイルから該当データの表示させたぃ・・
今は時間がないので簡潔な返答になってしまうことをお許しくださいm(__)m
しかも管理人さんと被ってますが投稿しておきます(^^;
>1.a.txtを開く
>2.a.txtを読み込む
>までしかわからないです。。
なるほど~。と言うことは構造体のところから分からないということですね。
データの一つを良く見ると
>番号 : 1
>名前 : tanaka taro
>クラス : A
>委員 : 美化
>年齢 : 16
番号、名前、クラス、委員、年齢で一人分のデータを表していますよね?
で、それぞれの項目は番号(整数値)、名前(文字列)、クラス(文字Or文字列)、委員(文字列)、年齢(整数値)と
なっていて型がばらばらになっています。
なのでそれぞれの項目を独立した配列に入れてもよいですが、これらをまとめて1人分の項目と出来ると扱いやすくなります。
そこで構造体の登場です。
参考にここの構造体などを参照してもらうと分かりやすいかと思います。
http://www9.plala.or.jp/sgwr-t/
一例として先ほどの項目をまとめて構造体DATAを作るとこんな感じになります。
(構造体が何かを理解してから下に進むと良いかと思います)
ちょっと時間がないのでここまでにしますが、ファイルの中身のそれぞれの項目は
: (コロンと半角スペース)の後に項目があると言うことでいいでしょうか?
ぁ、それとも読み込んだファイルからデータだけを抜き出すところは分かっているのかな?
何だか中途半端な説明で終わっていることをお許しください。
時間を見つけてまた書きます~。
しかも管理人さんと被ってますが投稿しておきます(^^;
>1.a.txtを開く
>2.a.txtを読み込む
>までしかわからないです。。
なるほど~。と言うことは構造体のところから分からないということですね。
データの一つを良く見ると
>番号 : 1
>名前 : tanaka taro
>クラス : A
>委員 : 美化
>年齢 : 16
番号、名前、クラス、委員、年齢で一人分のデータを表していますよね?
で、それぞれの項目は番号(整数値)、名前(文字列)、クラス(文字Or文字列)、委員(文字列)、年齢(整数値)と
なっていて型がばらばらになっています。
なのでそれぞれの項目を独立した配列に入れてもよいですが、これらをまとめて1人分の項目と出来ると扱いやすくなります。
そこで構造体の登場です。
参考にここの構造体などを参照してもらうと分かりやすいかと思います。
http://www9.plala.or.jp/sgwr-t/
一例として先ほどの項目をまとめて構造体DATAを作るとこんな感じになります。
(構造体が何かを理解してから下に進むと良いかと思います)
struct DATA{ int age; /*年齢*/ char name[20]; /*名前*/ char class[10]; /*クラス*/ char commission[20]; /*委員*/ int age; /*年齢*/ };これで構造体の準備ができたので次はファイルから読み込んでそれぞれの項目を抜き出す必要があります。
ちょっと時間がないのでここまでにしますが、ファイルの中身のそれぞれの項目は
: (コロンと半角スペース)の後に項目があると言うことでいいでしょうか?
ぁ、それとも読み込んだファイルからデータだけを抜き出すところは分かっているのかな?
何だか中途半端な説明で終わっていることをお許しください。
時間を見つけてまた書きます~。
Re:ファイルから該当データの表示させたぃ・・
例えば、今
num:7
name:taro
num:2
name:eri
num:4
name:tomo
num:3
name:satoshi
以上のような、番号と名前があるとします。
扱いやすいように、このようにデータが並んでいるとします。
このとき、番号を入力して、対応した名前を表示するプログラムは以下の通りです。
意地悪ではありませんが、これを改良しただけでは課題は出来ません。
色々上記の通りではうまくいかないように書いてあります。
そうしないと答えそのものになってしまうので・・。
これはこれを利用して課題を解いて欲しいわけではなく、流れをつかんでいただきたいのです。
また、上記プログラムの意味がわからなければそれでも結構です。
人の書いたプログラムを理解するのは大変です。
人に答えを聞くより、考え方を聞いて自分で一から作ったほうが早いんだと感じていただけたらそちらでも結構ですし。
まず、特定の文字列発見、構造体に格納、という2つをやってみましょう。
いきなりファイルから文章を読み込むのではなく、自分で文字列を作ってみてそこから特定の文字列を発見させてみましょう。
num:7
name:taro
num:2
name:eri
num:4
name:tomo
num:3
name:satoshi
以上のような、番号と名前があるとします。
扱いやすいように、このようにデータが並んでいるとします。
num:7 name:taro num:2 name:eri num:4 name:tomo num:3 name:satoshi
このとき、番号を入力して、対応した名前を表示するプログラムは以下の通りです。
#include <stdio.h>
typedef struct{
int num;//番号格納用変数
char name[128];//名前格納用変数
}student_t;
void main(){
int i=0,s=0,j=0,serch;
student_t student[100];
char st[/url]="num:7 name:taro num:2 name:eri num:4 name:tomo num:3 name:satoshi";
while(st!='\0'){//調査配列要素が最後ではない間ループ
if(st=='n' && st[i+1]=='u' && st[i+2]=='m' && st[i+3]==':')
student[j].num=st[i+4]-'0';//文字型データをint型データに変換して番号を格納
if(st=='n' && st[i+1]=='a' && st[i+2]=='m' && st[i+3]=='e' && st[i+4]==':'){
i+=5;//名前のデータのある配列要素へ移動
while(st!=' '){//名前が終わりになるまでループ
student[j].name=st;//名前を順々に格納
i++;
s++;
}
student[j].name='\0';//最後に終端記号を入れる
s=0;
j++;
}
i++;
}
printf("input num->");
scanf("%d",&serch);
for(i=0;i<j;i++){
if(student.num==serch){
printf("%d番の名前は%sです。\n",student.num,student.name);
return ;
}
}
printf("その番号は存在しません。\n");
return ;
}
意地悪ではありませんが、これを改良しただけでは課題は出来ません。
色々上記の通りではうまくいかないように書いてあります。
そうしないと答えそのものになってしまうので・・。
これはこれを利用して課題を解いて欲しいわけではなく、流れをつかんでいただきたいのです。
また、上記プログラムの意味がわからなければそれでも結構です。
人の書いたプログラムを理解するのは大変です。
人に答えを聞くより、考え方を聞いて自分で一から作ったほうが早いんだと感じていただけたらそちらでも結構ですし。
まず、特定の文字列発見、構造体に格納、という2つをやってみましょう。
いきなりファイルから文章を読み込むのではなく、自分で文字列を作ってみてそこから特定の文字列を発見させてみましょう。
Re:ファイルから該当データの表示させたぃ・・
皆さんからアドバイスを頂ぃて考ぇたのですが、
どうしても、ファイルから読み込み、構造体へ格納ができません。
どうしても、ファイルから読み込み、構造体へ格納ができません。
番号 : 1 名前 : tanaka taro クラス : A 委員 : 美化 年齢 : 16 番号 : 2 名前 : yamada jiro クラス : B 委員 : 体育 年齢 : 16 番号 : 3 名前 : tanaka haru クラス : C 委員 : 保健 年齢 : 16 番号 : 4 名前 : yamamoto itiro クラス : D 委員 : 図書 年齢 : 16
struct DATA{ int age; /*年齢*/ char name[20]; /*名前*/ char class[10]; /*クラス*/ char commission[20]; /*委員*/ int age; /*年齢*/ };わかる方ぃましたらお願ぃしますぅ(ーー;)
Re:ファイルから該当データの表示させたぃ・・
>どうしても、ファイルから読み込み、構造体へ格納ができません。
chii☆さんが、具体的にどのようなコードをお書きになって格納できていないのか
提示されていませんので、どこが間違っているのかをお答えできません。
現状のソースコードを提示願います。
chii☆さんが、具体的にどのようなコードをお書きになって格納できていないのか
提示されていませんので、どこが間違っているのかをお答えできません。
現状のソースコードを提示願います。
Re:ファイルから該当データの表示させたぃ・・
>keichanさん
申し訳ぁりません。。
申し訳ぁりません。。
#include<string.h> #include<stdio.h> #include <stdlib.h> struct Date{ char name[20]; //名前 char clas[10]; //クラス char commission[20]; //委員 int age; //年齢 }; void main(void){ FILE *fp; struct Date st_dt[100]; char c[20]; memset(c,NULL,sizeof(c)); fp = fopen("ex3.fil","r"); if ( fp == 0 ){ printf("open error\n"); exit(1); } while (fgets(c,20,fp) != NULL){ } }途中までしかできてぃませんが、宜しくお願ぃします。
Re:ファイルから該当データの表示させたぃ・・
while( fgets(c, 20, fp) != NULL )
の中にどういうコードを書けばいいのか分からない。
ということですね?
処理内容の順番は分かりますか?
fgets()関数は1行分の文字列を取得する関数です。
テキストには
1.番号
2.名前
3.クラス
4.委員
5.年齢
と5行を使用して1つの構造体の意味をなす情報が格納されています。
現在のテキストから読み込み格納先インデックス管理用変数を一つ用意して、
・毎行読み込みを行う度に"番号"が含まれているかをチェックして、含まれていれば次の格納先を指定する。
・後は同じ様に"名前", "クラス", "委員", "年齢"が読み込んだ行に含まれているかチェックして適宜対応する構造体メンバ変数に情報を格納する処理を書いてあげる。
これは 2007/05/15(火) 14:43 で管理人さんがヒントを出されているので、そちらの方を熟読して頑張ってみてください。
の中にどういうコードを書けばいいのか分からない。
ということですね?
処理内容の順番は分かりますか?
fgets()関数は1行分の文字列を取得する関数です。
テキストには
1.番号
2.名前
3.クラス
4.委員
5.年齢
と5行を使用して1つの構造体の意味をなす情報が格納されています。
現在のテキストから読み込み格納先インデックス管理用変数を一つ用意して、
void main(void){ FILE *fp; struct Date st_dt[100]; char c[20]; int index = -1; [color=#00ff00>/* Date構造体の格納先インデックス */[/color]
・毎行読み込みを行う度に"番号"が含まれているかをチェックして、含まれていれば次の格納先を指定する。
while (fgets(c,20,fp) != NULL){ [color=#00ff00>/* * strstr()関数は文字列内で最初に出現する検索文字列へのポインタを返す * 検索文字が見つからなかった場合は NULL を返す */[/color] if( strstr(c, "番号") != NULL ) { index++; } }
・後は同じ様に"名前", "クラス", "委員", "年齢"が読み込んだ行に含まれているかチェックして適宜対応する構造体メンバ変数に情報を格納する処理を書いてあげる。
これは 2007/05/15(火) 14:43 で管理人さんがヒントを出されているので、そちらの方を熟読して頑張ってみてください。
Re:ファイルから該当データの表示させたぃ・・
度々ごめんなさぃ↓↓
”番号”
を見付けても、ぅまく構造体に格納ができなぃです。。
申し訳ぁりませんが、どなたか助けてくださぃ!!
”番号”
を見付けても、ぅまく構造体に格納ができなぃです。。
while(fgets(c,20,fp) != NULL) { if( strstr(c, "社員番号 : ") != NULL ) { pc=strstr(c,"番号 : "); memcpy(st_dt.No,pc+1,1); } }
申し訳ぁりませんが、どなたか助けてくださぃ!!
Re:ファイルから該当データの表示させたぃ・・
仕様が変わっているように見えますが。
>if( strstr(c, "社員番号 : ") != NULL )
今までの 番号 が社員番号 に変更されているように見受けられますが・・・?
また、struct Dateのメンバに No を追加なされたようですが、型は何でしょうか?
>memcpy(st_dt.No,pc+1,1);
とされているので、char か unsigned char型・・・?
>pc=strstr(c,"番号 : ");
strstr関数はc配列の中から見つかった検索文字列の 先頭アドレス が返ってきます。
よって
開発環境が書かれていませんので、何ともいえないですが
もしデバッグ環境があるのであれば所々にブレークポイントを置いて
各変数の中身の状態を確認されることをお勧めします。
>if( strstr(c, "社員番号 : ") != NULL )
今までの 番号 が社員番号 に変更されているように見受けられますが・・・?
また、struct Dateのメンバに No を追加なされたようですが、型は何でしょうか?
>memcpy(st_dt.No,pc+1,1);
とされているので、char か unsigned char型・・・?
>pc=strstr(c,"番号 : ");
strstr関数はc配列の中から見つかった検索文字列の 先頭アドレス が返ってきます。
よって
+----+----+----+----+---+---+---+---+ | 社 | 員 | 番 | 号 | | : | | 1 | +----+----+----+----+---+---+---+---+ ↑ pcはここを示すアドレスが格納されている
開発環境が書かれていませんので、何ともいえないですが
もしデバッグ環境があるのであれば所々にブレークポイントを置いて
各変数の中身の状態を確認されることをお勧めします。
Re:ファイルから該当データの表示させたぃ・・
ちょっと今時間がないので即席になってしまいましたが、
お書きになったコードにstrstrとmemcpyがあったんで、
それと、元々お書きになったコードを最大限いかして、書いてみました。
keichanさんの、回答を熟読して、それでもわからなければ以下参考にしてください。
ちょっと確かめてないんですけど、これで、読み込んだものが表示できているはずです。
後はswitch文かif文などで条件分岐してstrに入っている欲しいデータをそれぞれ構造体にいれたらいいだけです。
お書きになったコードにstrstrとmemcpyがあったんで、
それと、元々お書きになったコードを最大限いかして、書いてみました。
keichanさんの、回答を熟読して、それでもわからなければ以下参考にしてください。
#include<string.h>
#include<stdio.h>
#include <stdlib.h>
struct Date{
int num; //番号
char name[20]; //名前
char clas[10]; //クラス
char commission[20]; //委員
int age; //年齢
};
void main(void){
int serch_i=0;
char str[128]="";
char serch[5][128]={"番号 : ","名前 : ","クラス : ","委員 : ","年齢 : "};
char *sp;
FILE *fp;
struct Date st_dt[100];
char c[256];
fp = fopen("test.txt","r");
if ( fp == 0 ){
printf("open error\n");
exit(1);
}
while (fgets(c,256,fp) != NULL){//1行読み込み
for(serch_i=0;serch_i<5;serch_i++){//探す5行分ループ
if((sp = strstr(c,serch[serch_i])) == NULL)//現在調査中のserch内容が無かったら次
continue;
else{//あったら
sp+=strlen(serch[serch_i]);//探索した文字分シフト。例えば"番号 : "のバイト分だけシフト
memcpy(str,sp,strlen(sp)-1);//改行コードが最後にあるので、その手前までコピー
str[strlen(sp)-1]='\0';//最後に終端記号をつける。
printf("%s\n",str);
}
}
}
return ;
}
ちょっと確かめてないんですけど、これで、読み込んだものが表示できているはずです。
後はswitch文かif文などで条件分岐してstrに入っている欲しいデータをそれぞれ構造体にいれたらいいだけです。
Re:ファイルから該当データの表示させたぃ・・
皆様ご丁寧に、ほんとおぉにぁりがとぉござぃます(●^@^●)
何かぉ礼をしたぃくらいです(#^●^#)
管理人さんのサンプルから構造体に格納の仕方ですが、
何かぉ礼をしたぃくらいです(#^●^#)
管理人さんのサンプルから構造体に格納の仕方ですが、
else //あったら { sp = sp + strlen(serch[serch_i]); if(strstr(c,"番号")) { memcpy(str,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; st_dt.num = atoi(str); } else if(strstr(c,"名前")) { memcpy(st_dt.name,sp,strlen(sp)-1); st_dt.name[strlen(sp)-1]=NULL; } else if(strstr(c,"クラス")) { memcpy(st_dt.class,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; } else if(strstr(c,"委員")) { memcpy(st_dt.commission,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; } else if(strstr(c,"年齢")) { memcpy(str,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; st_dt.age = atoi(str); } break; } 上手く表示されないのですが、どこがぉかしぃのでしょうかぁ?? 何回もすみません。。
Re:ファイルから該当データの表示させたぃ・・
せっかくサンプルをお書きしたので、じっくり見てください。
ちょっと厳しいようですが、見る限りではサンプルの意味を理解していないように思います。
比較すべき文字列は既に用意してありますよね。
注釈も書いています。
もし私の書いたプログラムの特定の箇所がわからなければ、「ここがわからない」と言ってください。
上のサンプルを実行してもらえばわかるはずですが、もう取得すべき文字列はstrに入っているんです。
それを構造体にいれたらいいだけです。
なお、strstrは使う必要ないですよね。
すでにstrにほしい文字列ははいっているので、その文字列がどの欲しい文字列と一致するのか
調べて格納すればいいのです。
http://www.google.co.jp/search?hl=ja&q= ... %BC%83&lr=
この辺で探して変更してみましょう。
ちょっと厳しいようですが、見る限りではサンプルの意味を理解していないように思います。
比較すべき文字列は既に用意してありますよね。
注釈も書いています。
もし私の書いたプログラムの特定の箇所がわからなければ、「ここがわからない」と言ってください。
上のサンプルを実行してもらえばわかるはずですが、もう取得すべき文字列はstrに入っているんです。
それを構造体にいれたらいいだけです。
なお、strstrは使う必要ないですよね。
すでにstrにほしい文字列ははいっているので、その文字列がどの欲しい文字列と一致するのか
調べて格納すればいいのです。
http://www.google.co.jp/search?hl=ja&q= ... %BC%83&lr=
この辺で探して変更してみましょう。
Re:ファイルから該当データの表示させたぃ・・
あ、そういえば既にループの中で現在どの文字列に一致しているかわかっているので、比較する必要はありませんね。
本当にただ後はいれたらいいだけです。
本当にただ後はいれたらいいだけです。
Re:ファイルから該当データの表示させたぃ・・
何度も何度もアドバイスぁりがとぅございました!!!
このようにしましたぁ!!!
else //あったら { sp = sp + strlen(serch[serch_i]); if(serch_i == 0) { memcpy(str,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; st_dt.num = atoi(str); } else if(serch_i == 1) { memcpy(st_dt.name,sp,strlen(sp)-1); st_dt.name[strlen(sp)-1]=NULL; } else if(serch_i == 2) { memcpy(st_dt.class,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; } else if(serch_i == 3) { memcpy(st_dt.commission,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; } else if(serch_i == 4) { memcpy(str,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; st_dt.age = atoi(str); i++; } break; }
このようにしましたぁ!!!
Re:ファイルから該当データの表示させたぃ・・
そうそう・・・
そうなんですが、コンパイルしてみましたか?
予測通りの結果は得られていないんじゃないかと思いますが。
とりあえず、やり方あってるんですけど、途中から混乱してしまったように感じます。
最初の条件文内はあっていますが、次はstrにいれてしまっています。
いっぺんにやってしまうならstrは必要ありませんので、消しといてください。
そちらの方が解りやすいかなと思って用意しただけなんで。
プログラム出来たらコンパイルして結果が得られたかどうか確認してください。
そうなんですが、コンパイルしてみましたか?
予測通りの結果は得られていないんじゃないかと思いますが。
とりあえず、やり方あってるんですけど、途中から混乱してしまったように感じます。
else if(serch_i == 1) { memcpy(st_dt.name,sp,strlen(sp)-1); st_dt.name[strlen(sp)-1]=NULL; } else if(serch_i == 2) { memcpy(st_dt.class,sp,strlen(sp)-1); str[strlen(sp)-1]=NULL; }
最初の条件文内はあっていますが、次はstrにいれてしまっています。
いっぺんにやってしまうならstrは必要ありませんので、消しといてください。
そちらの方が解りやすいかなと思って用意しただけなんで。
プログラム出来たらコンパイルして結果が得られたかどうか確認してください。
Re:ファイルから該当データの表示させたぃ・・
私はこんな風に書きました。
なお、プログラム中に出てくる
この関数は、指定されたiの内容を表示するだけの関数です。
特に難しいことはしていません。
内容もほとんど変更していません。
switch文が増えただけです。
なお、プログラム中に出てくる
void disp(struct Date st_dt[MAX_N] , int i){ printf("番号 = %d\n",st_dt[1].num); printf("名前 = %s\n",st_dt[1].name); printf("クラス = %s\n",st_dt[1].clas); printf("委員 = %s\n",st_dt[1].commission); printf("年齢 = %d\n",st_dt[1].age); return ; }
この関数は、指定されたiの内容を表示するだけの関数です。
特に難しいことはしていません。
内容もほとんど変更していません。
switch文が増えただけです。
#include<string.h> #include<stdio.h> #include <stdlib.h> #define BUF 256 #define MAX_N 100 struct Date{ int num; //番号 char name[BUF]; //名前 char clas[BUF]; //クラス char commission[BUF]; //委員 int age; //年齢 }; void disp(struct Date st_dt[MAX_N] , int i){ printf("番号 = %d\n",st_dt[1].num); printf("名前 = %s\n",st_dt[1].name); printf("クラス = %s\n",st_dt[1].clas); printf("委員 = %s\n",st_dt[1].commission); printf("年齢 = %d\n",st_dt[1].age); return ; } void main(void){ int serch_i=0,st_dt_i=0; char str[BUF]=""; char serch[5][BUF]={"番号 : ","名前 : ","クラス : ","委員 : ","年齢 : "}; char *sp; FILE *fp; struct Date st_dt[MAX_N]; char c[BUF]; fp = fopen("test.txt","r"); if ( fp == 0 ){ printf("open error\n"); exit(1); } while (fgets(c,BUF,fp) != NULL){//1行読み込み for(serch_i=0;serch_i<5;serch_i++){//探す5行分ループ if((sp = strstr(c,serch[serch_i])) == NULL)//現在調査中のserch内容が無かったら次 continue; else{//あったら sp+=strlen(serch[serch_i]);//探索した文字分シフト。例えば"番号 : "のバイト分だけシフト memcpy(str,sp,strlen(sp)-1);//改行コードが最後にあるので、その手前までコピー str[strlen(sp)-1]='\0';//最後に終端記号をつける。 switch(serch_i){ case 0: st_dt[st_dt_i].num=atoi(str); break; case 1: strcpy(st_dt[st_dt_i].name,str); break; case 2: strcpy(st_dt[st_dt_i].clas,str); break; case 3: strcpy(st_dt[st_dt_i].commission,str); break; case 4: st_dt[st_dt_i].age=atoi(str); st_dt_i++; break; } } } } disp(st_dt,1); return ; }
Re:ファイルから該当データの表示させたぃ・・
今回番号は順番のようですが、番号は順不同だとします。
ファイルデータはこのようなデータだとしましょう。
http://dixq.net/txt/test.txt
(対象をファイルに保存してください。)
今回番号を指定して、そのデータを探させます。
探す番号をnumに持たせて関数を開始し、内容を調べて、どの配列要素にデータがあるか、その番号を返します。
最後まで見つからなかったら-1を返します。
これを使って以下のようにプログラムを書いてみました。
一度実行してみてください。
最後に無駄に色々メッセージを表示させていますが、この内容を見れば後どうすればいいかわかるでしょう。
今回番号を指定して内容を探索しましたが、
serch_numの内容を変更したり、似たような関数をもう一つ作ったりすることで
名前から検索したり、委員名から探索したりすることも出来ることがわかりますね。
もし時間があればもっと色々機能を付けてみてください。
ファイルデータはこのようなデータだとしましょう。
http://dixq.net/txt/test.txt
(対象をファイルに保存してください。)
今回番号を指定して、そのデータを探させます。
int serch_num(struct Date st_dt[MAX_N] , int num){ int i; for(i=0;i<MAX_N;i++){ if(st_dt.num==num) return i; } return -1; }
探す番号をnumに持たせて関数を開始し、内容を調べて、どの配列要素にデータがあるか、その番号を返します。
最後まで見つからなかったら-1を返します。
これを使って以下のようにプログラムを書いてみました。
一度実行してみてください。
最後に無駄に色々メッセージを表示させていますが、この内容を見れば後どうすればいいかわかるでしょう。
#include<string.h> #include<stdio.h> #include <stdlib.h> #define BUF 256 #define MAX_N 100 struct Date{ int num; //番号 char name[BUF]; //名前 char clas[BUF]; //クラス char commission[BUF]; //委員 int age; //年齢 }; int serch_num(struct Date st_dt[MAX_N] , int num){//番号を検索 int i; for(i=0;i<MAX_N;i++){ if(st_dt.num==num) return i;//見つかった配列要素番号 } return -1;//検索出来なかった } void disp(struct Date st_dt[MAX_N] , int i){//指定された配列要素番号のデータを表示 printf("番号 = %d\n",st_dt.num); printf("名前 = %s\n",st_dt.name); printf("クラス = %s\n",st_dt.clas); printf("委員 = %s\n",st_dt.commission); printf("年齢 = %d\n",st_dt.age); return ; } void main(void){ int serch_i=0,st_dt_i=0,n,st_dt_n; char str[BUF]=""; char serch[5][BUF]={"番号 : ","名前 : ","クラス : ","委員 : ","年齢 : "}; char *sp; FILE *fp; struct Date st_dt[MAX_N]; char c[BUF]; fp = fopen("test.txt","r"); if ( fp == 0 ){ printf("open error\n"); exit(1); } while (fgets(c,BUF,fp) != NULL){//1行読み込み for(serch_i=0;serch_i<5;serch_i++){//探す5行分ループ if((sp = strstr(c,serch[serch_i])) == NULL)//現在調査中のserch内容が無かったら次 continue; else{//あったら sp+=strlen(serch[serch_i]);//探索した文字分シフト。 memcpy(str,sp,strlen(sp)-1);//改行コードの手前までコピー str[strlen(sp)-1]='\0';//最後に終端記号をつける。 switch(serch_i){ case 0: st_dt[st_dt_i].num=atoi(str); break;//番号を格納 case 1: strcpy(st_dt[st_dt_i].name,str); break;//名前を格納 case 2: strcpy(st_dt[st_dt_i].clas,str); break;//クラスを case 3: strcpy(st_dt[st_dt_i].commission,str); break;//委員を case 4: st_dt[st_dt_i].age=atoi(str); st_dt_i++; break;//年齢を } } } } printf("番号を入力->\n"); scanf("%d",&n); st_dt_n = serch_num(st_dt,n);//番号nのデータは配列要素番号st_dt_nにある if(st_dt_n!=-1) printf("この番号はst_dt[%d]のデータ\n",st_dt_n); else{ printf("その番号はありません。\n"); return ; } printf("\n\n\n例えばst_dt[0]のデータは\n\n"); disp(st_dt, 0);//配列要素番号0番目のデータを表示 return ; }
今回番号を指定して内容を探索しましたが、
serch_numの内容を変更したり、似たような関数をもう一つ作ったりすることで
名前から検索したり、委員名から探索したりすることも出来ることがわかりますね。
もし時間があればもっと色々機能を付けてみてください。
Re:ファイルから該当データの表示させたぃ・・
なお、文字列が長すぎたときや、其の他諸々するべきエラー処理は何もしていませんから、
完璧なプログラムを目指すならエラーの置きそうな箇所全てにエラー処理をしておきましょう。
例えば上記で言えば、
else{
printf("その番号はありません。\n");
return ;
}
このような部分がエラー処理ですね。
完璧なプログラムを目指すならエラーの置きそうな箇所全てにエラー処理をしておきましょう。
例えば上記で言えば、
else{
printf("その番号はありません。\n");
return ;
}
このような部分がエラー処理ですね。
Re:ファイルから該当データの表示させたぃ・・
こんなに丁寧にご教授下さって本当にぁりがとうござぃます!!!
この機能から、簡単な名簿システム(登録、検索、削除、更新)なようなものを作ってみようと思ぃます。
もし名簿システムを作る上で、ヒント(コツ)のようなものがあればお願ぃ致します☆
本当にぁりがとうござぃました!!!
またわからなぃところがぁれば申し訳ぁりませんが、ご教授願ぃます。
この機能から、簡単な名簿システム(登録、検索、削除、更新)なようなものを作ってみようと思ぃます。
もし名簿システムを作る上で、ヒント(コツ)のようなものがあればお願ぃ致します☆
本当にぁりがとうござぃました!!!
またわからなぃところがぁれば申し訳ぁりませんが、ご教授願ぃます。
Re:ファイルから該当データの表示させたぃ・・
名簿システムを作るうえでのコツ・・。
特に無いのでは^^;
スキルアップのコツと言う意味では・・、
標準関数に頼り過ぎないって事でしょうか。
例えば、atoi関数ってありますよね。
文字列を数値に変換する関数ですよね。
しかしあんなのは標準関数使わなくても出来ますよね。
ですからatoiならぬa2i関数などを自作して、文字列からintに変換する自作関数を作ってみたりしてはいかがでしょうか。
またstrlenにしてもstrcpyにしても、自分で、stringlenやstrcopyなどちょいと名前を変えた自作関数を
作ってみて、なるべく標準関数を使わないようにプログラムしてみるとか。
すると内部の処理がよくわかりますよ。
ちなみにatoiでは
文字コード - '0'
を計算する事で、一桁の数値が計算できますし、
stringlenでは、\0までの配列要素数をカウントすればよいだけ、
strcopyは中身をそのままコピーしたらいいだけですね。
私自身標準関数がいろいろある事をしったのは随分入門時から後のことでして、最初から自分で処理を書いていました。
今となっては結局そちらの方が近道だったのではないかと思っています。
特に無いのでは^^;
スキルアップのコツと言う意味では・・、
標準関数に頼り過ぎないって事でしょうか。
例えば、atoi関数ってありますよね。
文字列を数値に変換する関数ですよね。
しかしあんなのは標準関数使わなくても出来ますよね。
ですからatoiならぬa2i関数などを自作して、文字列からintに変換する自作関数を作ってみたりしてはいかがでしょうか。
またstrlenにしてもstrcpyにしても、自分で、stringlenやstrcopyなどちょいと名前を変えた自作関数を
作ってみて、なるべく標準関数を使わないようにプログラムしてみるとか。
すると内部の処理がよくわかりますよ。
ちなみにatoiでは
文字コード - '0'
を計算する事で、一桁の数値が計算できますし、
stringlenでは、\0までの配列要素数をカウントすればよいだけ、
strcopyは中身をそのままコピーしたらいいだけですね。
私自身標準関数がいろいろある事をしったのは随分入門時から後のことでして、最初から自分で処理を書いていました。
今となっては結局そちらの方が近道だったのではないかと思っています。