
ファイルをfscanfを使って文字列を構造体に格納して読み込みたいのですが読み込み方の記述方法がわか
りません。
どのようにしたら読み込めますか?
以下ソース
---ソース---
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct info //1回目の呼び出し方法
{
char name[20];
char mb[20];
}deta;
struct info2 //2回目の呼び出し方法
{
char *name;
char *mb;
}deta2;
struct info3 //3回目の呼び出し方法
{
char *name[6];
char *mb[6];
}deta3;
void main(void){
FILE *fp;
fp=fopen("yasa.txt","r+");
while( !feof( fp ) ){
fscanf( fp, "%s %s",deta.name,deta.mb );
printf("%s %s\n",deta.name,deta.mb);
}
rewind( fp );
//2回目の呼び出し方法での記述の仕方がわからない
rewind( fp );
//3回目の呼び出し方法での記述の仕方がわからない
fclose(fp);
}
---yasa.txtの内容---
オレンジ ●
みかん ●
いちご ×
もも ●
ぶどう ×
キウイ ●
No.1ベストアンサー
- 回答日時:
>//2回目の呼び出し方法での記述の仕方がわからない
deta2はポインタ変数しか持っていませんのでmalloc()などで必要な領域を確保してから、
その場所(ポインタが指している先)に読み込んで下さい。
問題は「確保するべき領域のサイズが判らない」ということですが…。
char ReadTemp1[100],ReadTemp2[100];
とかを用意して、
fscanf( fp, "%s %s",ReadTemp1,ReadTemp2 );
deta2.name = malloc(strlen(ReadTemp1)+1); //'\0'の分が必要
strcpy(deta2.name, ReadTemp1);
deta2.mb = malloc(strlen(ReadTemp2)+1); //'\0'の分が必要
strcpy(deta2.mb, ReadTemp1);
という感じで入れます。
# 使い終わった後の開放を忘れずに。
ちなみにdeta2は1個分子かありませんから、続きのデータは読めません。
detaと同じように、その場で使うだけならその都度開放して下さい。
deta3は、ポインタの配列が6個分ありますからそれぞれに領域確保して読み込ませておくこともできるでしょう。
やり方自体はdata2の時のように作業用領域に読み込んでメモリ確保して、コピーして…の繰り返しです。
この回答への補足
なるほどmallocを使うのですね
ぜんぜん思いつきませんでした
ソースも書いていただきありがとうございます。
開発可能なPCに戻して試してみますね
できました
こんな感じですね
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct info //1回目の呼び出し方法
{
char name[20];
char mb[20];
}deta;
struct info2 //2回目の呼び出し方法
{
char *name;
char *mb;
}deta2;
struct info3 //3回目の呼び出し方法
{
char *name[6];
char *mb[6];
}deta3;
void main(void){
FILE *fp;
char n[100],m[100];
char a[6][100],b[6][100];
int i=0;
fp=fopen("yasa.txt","r+");
while( !feof( fp ) ){
fscanf( fp, "%s %s",deta.name,deta.mb);
printf("%s %s\n",deta.name,deta.mb);
}
printf("\n");
rewind( fp );
while( !feof( fp ) ){
fscanf( fp, "%s %s",n,m);
deta2.name= (char*)malloc(strlen(n)+1);
strcpy(deta2.name, n);
deta2.mb= (char*)malloc(strlen(m)+1);
strcpy(deta2.mb, m);
printf("%s %s\n",deta2.name,deta2.mb);
free(deta2.name);
free(deta2.mb);
}
printf("\n");
rewind( fp );
while( !feof( fp ) ){
fscanf( fp, "%s %s",a[i],b[i]);
deta3.name[i]= (char*)malloc(strlen(a[i])+1);
strcpy(deta3.name[i], a[i]);
deta3.mb[i]= (char*)malloc(strlen(b[i])+1);
strcpy(deta3.mb[i], b[i]);
printf("%s %s\n",deta3.name[i],deta3.mb[i]);
free(deta3.name[i]);
free(deta3.mb[i]);
i++;
}
fclose(fp);
}
No.6
- 回答日時:
>そのため、サーバー管理会社は使いません。
迷惑をかける可能性が少しでもあるからそのため多額な賠償請求もされません。
ちょっと考えが甘いです。
もし、あなたが運用されるサーバーが踏み台にされ他者に迷惑をかけた場合、加害者扱いになる可能性がありますので迷惑をかけたところからの賠償請求はありえます。
その話は聞いてますよ
そのためアタック対策は万全にしようって話ですね
もちろん忘れてはいませんよ
今はまだ少ししか対策していませんがこれからゆっくり対策していきますよ
どんなものでも一気に全部できるわけではないので、少しづつ作っていきます
No.5
- 回答日時:
> あふれたデータ云々はよくわからないようなことになりそうなら、プログラムとして問題ないなら放置。
> バグがでてきたらその時処理するでしょうね。
こんな考えでC言語、特にポインタ絡みの操作を使ってほしくないです。
御自身のPCが壊れるだけなら自業自得で済みますが、これでCGIを作ろうとしてますよね?
被害が全世界に及ぶ可能性とか、サーバー管理社から多額の賠償請求される可能性とか、考えたことありますか?
この回答への補足
といいますか私は教科書もなければ師事する先生もいないのでCGIを作って完成させたとしても
私から見れば正常なプログラムでももしかしたら「おかしなプログラム」を作っている可能性は十分ありえる。
その点はCGIを作る時に常に考えてますよ。
何せちゃんと動いてるのかわからないですからね。
そのため、サーバー管理会社は使いません。迷惑をかける可能性が少しでもあるから
そのため多額な賠償請求もされません。
私が使うのは自宅サーバーですよ。
ですから、壊れたとしても自業自得ですみますよ。
それにPCはすでに壊れてますしね。
それに私がどんな考え方だとしても。
C言語を使って楽しむのは非常に面白いのですよ。
皆さんが何の理由でC言語を使っているのかは分かりません。
仕事のため、プログラムの勉強のため等さまざまな理由でしょう。
私はC言語を使って楽しみたいからと言うのも理由であれば少しづつ目的となるプログラムを作っていくのが面白いのです。
材料が全くなくてもできますしね。
ちなみにこうは言いますが、決していい加減なものを作るつもりはありませんよ
何せ私が作る作品を愛していますからね。
例え他の人が私のやり方では愛していないように見えるのでしたら、それでもかまいませんよ
ですが他の人がなんと言おうとも私は自分の作品を愛してます。
確かに私はバグがでるまで待っているところはありますが、師事する先生も教科書もないならバグと向き合ってバグの対処法を覚える事で、いろいろな可能性が見えてくるのです。
試行錯誤はけっこうしますが、それは決して無駄な事ではないと考えています。
No.4
- 回答日時:
>1が必須の理由が分からないです。
>なぜなのでしょうか?(長さを指定しなくても動いたので)
バッファオーバーランを実施することができるから…です。
現在は20バイト確保していますが、そこに200文字読み込ませることもできます。
未指定ですからね。
そして、あふれたデータがどこに書き込まれるのか?
ということです。
# セキュリティホール関係で「バッファオーバーランにより任意のコードが実行できる云々」というのはそういうモノです。
まぁ、そういう意味ではNo.1での私の回答もバッファオーバーランできるのですが。
この回答への補足
おやよく見たらお久しぶりです♪
元気そうで何よりですね
もうしばらくしたらクリスマスですよ
おいしいご飯が楽しみです。
Wr5さんもクリスマスはたのしみますか?
世間話はここまでにして、バッファオーバーランをここで聞く事になるとはおもいませんでした
なるほどです。
一定数の文字以上になったら禁止にしていたので気づきませんでした。
(練習用には書いてませんが)
あふれたデータ云々はよくわからないようなことになりそうなら、プログラムとして問題ないなら放置。
バグがでてきたらその時処理するでしょうね。
ただ、こう書くとバグになるでしょうっと思っていたものが書いた後は正常に動く事もあって面白いですよね
No.3
- 回答日時:
読み込み方法そのものは同じです
・fscanf( fp, "%s %s",nameを一時的に読み込む領域のポインタまたは配列,mbを一時的に読み込む領域のポインタまたは配列 );
・構造体のname,mbに、上記で読んだ内容を反映させる
struct info の場合、name,mbをそのまま「一時的に読み込む領域」として利用する方法もあります。それがそこに書かれているプログラムです。
それで、それぞれの構造体と、そのメンバーはどんな使い方をしたいのですか?
たとえばinfo2。 infoでのcharの配列をポインタにしてます。
ポインタは、対象へのアドレスでしかありません。fscanfで読み込むなら、別途その内容を記憶する領域が必要です。
その領域をどう用意するつもりなのでしょうか?
・mallocで動的に確保
・記憶用の大きな配列を用意して、その一部を使う
・記憶用info構造体を用意して、各メンバーへのポインタにする
それぞれに使い方が違います。
info3に至っては、なんでこんな構造体のデザインにしたのかがわかりません。
ファイルは1行にnameとmbで1セットで、それが6行ある、ってことですよね?
それなら、infoの配列とか、info2の配列にするのが自然でしょう。
この回答への補足
<<それで、それぞれの構造体と、そのメンバーはどんな使い方をしたいのですか?
ええっとこれは練習用のプログラムなのですが本当に作りたいプログラムは
・ログイン名、IP、リモートホストの3っつを記録して
・ログアウトしたら、記録から内容を消して
・『その内容を読み込んでログイン名のみ表示させる』
プログラムを作りたかったのです。
2番目の処理も苦戦中ですが、今回聞いてるのは3番目の処理をするときにどうしたらいいかの処理ですね
<<・mallocで動的に確保
・記憶用の大きな配列を用意して、その一部を使う
・記憶用info構造体を用意して、各メンバーへのポインタにする
それぞれに使い方が違います。
ですので、こう聞かれてるのですが幸いmallocならある程度使った事があるので1番目で記述する方法はある程度分かります
2番目や3番目がどういったものか分からないのですが、作りたいプログラムが無事できるのであれば2番目や3番目の方法で書くこっとも考えます。(ただあんまり知らない方法や関数で書かれると分からなくなるので1番目の方法で書くつもりではあります)
<<info3に至っては、なんでこんな構造体のデザインにしたのかがわかりません。
ファイルは1行にnameとmbで1セットで、それが6行ある、ってことですよね?
それなら、infoの配列とか、info2の配列にするのが自然でしょう。
その理由はあくまでこのプログッラムが練習用であることとinfo2とinfo3がもしかしたら書き方がぜんぜん違う可能性を考えて質問しましたし、処理の仕方の2番目でそこらへんを知っておくとうまく処理の方法を思いつくのではないかと思って質問しました。
他にも私のプログラムの覚え方が特殊だから変な質問をしてると感じるかもしれませんが
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
init関数の意味
-
C言語のポインタに直接アドレス...
-
ポインターの使用法や利点
-
セグメントエラー
-
参照型で受け取った引数をポイ...
-
関数ポインタの高速化のメリット
-
C++のNULLは意味があるの?
-
Run-Time Check Failure #3とい...
-
PASCALとFARの意味
-
#define NULL ((void *)0) の弊害
-
引き数がポインタでない関数の...
-
【C言語】戻り値が構造体の関数
-
アプリを32bitから64bit移行
-
なぜエラーが出るのでしょうか?
-
戻り値で構造体を返すことは可...
-
C++:関数の戻り値で 【void *...
-
ExcelVBAでのkernel32(64bit)
-
NULLとブランクの違い
-
NULLポインタが0でない処理系と...
-
どうしてエラーになるかわかり...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
ExcelVBAでのkernel32(64bit)
-
アプリを32bitから64bit移行
-
参照型で受け取った引数をポイ...
-
fopne で失敗する原因
-
PASCALとFARの意味
-
LPSTR型の初期化について
-
CWnd::EnableWindow()の扱い方
-
ポインタについて
-
プーさんのマウスポインタを教...
-
連結リスト 要素の入れ替え
-
ハンドルはポインタか
-
C++で関数ポインタから関数名を...
-
自作DLLの引数について、ポイン...
-
NULLポインタが0でない処理系と...
-
TCHAR文字列内の検索について
おすすめ情報