C言語の勉強をしております。
双方向リストへのデータの登録でうまくいかず詰まってしまいました。
<ヘッダファイル>
// 構造体
typedef struct address {
char names[32];/* 名前 */
char tels[32];/* 電話番号 */
struct address *prev;/* 前へのポインタ */
struct address *next;/* 次へのポインタ */
}Address;
extern Address *top_pt;
extern Address *work_pt;
extern Address *w_pt;
extern Address *inAdd;
// ファイルからの読み込み
top_pt = NULL;
while(!feof(fp)) {
work_pt = (Address *)malloc(sizeof(Address));
if(!work_pt){
printf("メモリ不足");
exit(1);
}
fscanf(fp, "%s %s", work_pt->tels, work_pt->names);
work_pt->next = top_pt;
top_pt = work_pt;
work_pt->prev = top_pt;
/* カウンタを用意して、実際のデータ件数をカウントしておく */
++trueCount;
}
これで、双方向リストへファイルの内容を格納することは出来ました。
次に、構造体へデータを新規登録したいのですが、構造体を共有している別ソースファイルにて、
for(i=0; 1000>trueCount+i; i++){
inAdd = (Address *)malloc(sizeof(Address));
if(!inAdd){
printf("メモリ不足");
exit(1);
}
printf("登録する名前を入力してください:");
gets(inAdd->names);
/* 名前が未入力でEnterされた場合 */
if(!*inAdd->names){
/* ループを抜け、トップメニューへ */
flag = 1;
break;
}
printf("電話番号を入力してください:");
scanf("%s", inAdd->tels);
/* 読み込んだ構造体へデータを追加する */
work_pt->next = inAdd;
inAdd->prev = work_pt;
inAdd->next = NULL;
}
として、構造体の中身を表示させたところ、
ファイルの最終データと、入力したデータのみになってしまいました。
なぜなのか分かりません・・・。
有識者の方でこの下手なソースを読んで指南していただける方はおられますでしょうか?
また、データ登録の際に名前の入力に「gets」を使用しているんですが、
「scanf」だとその次のif文が効かないみたいで少し困っています。
(出来ればANSIC標準のscanfを使いたい)
以上、よろしくお願いいたします。
No.9ベストアンサー
- 回答日時:
アドバイスの続きです。
>>●本当は、どのような動作を期待していましたか?
>ファイルから読み込んだデータに、入力したデータが追加されていくイメージです。
> データの入力を
> top_pt->next = inAdd;
> inAdd->prev = top_pt;
> inAdd->next = NULL;
> のようにしてもうまくいかなかったんですが、これもおかしいでしょうか?
・リストの先頭に要素を追加するなら、
inAdd->next = top_pt;/* 入力データのnextに今の先頭要素をリンク。 */
inAdd->prev = NULL;/* 入力データのprevにNULLを代入 */
top_pt->prev = inAdd;/* 先頭要素のprevに入力データをリンク。 */
top_pt = inAdd;/* 入力データを先頭要素とする */
で良いと思います。
・リストの末尾に要素を追加したい場合、
top_pt以外に、bottom_pt等を用意して、最終要素も管理してあげると良いのでは、
ないでしょうか。
・蛇足
アルゴリズムが理解できたら、次はもう一歩発展させて、要素に追加する処理を
関数化してみてはどうでしょう。
例えば、
/**
* 双方向リストの先頭にアイテムを追加する。
*
* @param[in] pItem 追加する要素
*/
int insertItemToTop(Address *pItem) {
[づらづら]
}
・蛇足その2
> また、ファイルの末尾のチェック方法についてですが、ループの途中に、fscanfとEOFを比較して、ループから抜けるようにしました。
>
> ごみデータが入ってしまう事は私も分かっており、悩んでいたんですが、回答者様のご指摘を参考に上記処理にて解決できました。(正しい方法なのかは分かりませんが・・・)
ファイル読込にも、fgets() + sscanf()の組み合わせが有効な場合もあるかもしれません。
アドバイスありがとうございます。
関数化について考えてみたいと思います。
また、fgetsとsscanの組み合わせの有効的な使用方法は分かりませんので、とりあえず私の分かる範囲で処理を記述してみたいと思います。
色々アドバイスありがとうございました。
No.8
- 回答日時:
標準に含まれているかどうかは, それこそ「標準を確認する」だけでわかるはずです. ANSI そのものには当たっていませんが, ISO や JIS の規格を調べれば「gets が標準に含まれている」ことは想像できるはずです. JIS なら
http://www.jisc.go.jp/
の「JIS 検索」で規格番号として「X3010」を入れれば閲覧だけは出来ます.
あと, この書き方では「最後にごみデータが入る」可能性があります. 「ファイルの末尾」のチェック方法によるもので, 実際に空のファイルを読み込ませてみれば簡単にわかるはず.
ありがとうございます。
また、ファイルの末尾のチェック方法についてですが、ループの途中に、fscanfとEOFを比較して、ループから抜けるようにしました。
ごみデータが入ってしまう事は私も分かっており、悩んでいたんですが、回答者様のご指摘を参考に上記処理にて解決できました。(正しい方法なのかは分かりませんが・・・)
ありがとうございました。
No.7
- 回答日時:
ああ, ついでにもう 1つですが, この
「ファイルからの読み込み」
のところは論理的にたぶん間違っています. この形で feof を使うのは危ない気がするなぁ.
No.5
- 回答日時:
●これは何をしめしていますか?
extern Address *top_pt;
extern Address *work_pt;
extern Address *w_pt;
extern Address *inAdd;
#推測
extern Address *top_pt;// 双方向リストの先頭要素
extern Address *work_pt;// 処理中データをしめすワーク
extern Address *w_pt;// 何??
extern Address *inAdd;// 入力中のデータ
> これで、双方向リストへファイルの内容を格納することは出来ました。
双方向リストの前方に、1件づつデータを追加していくアルゴリズムみたいですね。
> /* 読み込んだ構造体へデータを追加する */
> work_pt->next = inAdd;
> inAdd->prev = work_pt;
> inAdd->next = NULL;
この時点で work_pt はどこをさしているつもりですか?
私の予想だと work_pt は先頭要素ですね。
> work_pt->next = inAdd;
で、先頭要素のnextに入力データをリンク。
> inAdd->prev = work_pt;
入力データのprevに先頭要素をリンク。
> inAdd->next = NULL;
入力データのnextにNULLを代入。
しているので、
> として、構造体の中身を表示させたところ、
> ファイルの最終データと、入力したデータのみになってしまいました。
そのとおりの結果なのではないでしょうか?
●本当は、どのような動作を期待していましたか?
> また、データ登録の際に名前の入力に「gets」を使用しているんですが、
> 「scanf」だとその次のif文が効かないみたいで少し困っています。
> (出来ればANSIC標準のscanfを使いたい)
未入力でEnterが押された場合、scanfが再度入力待ちになるのは、正しい動作です。
未入力でEnterが押された場合を判定して、処理したい場合、
拙者なら、
----------------------------------------------------------------------
char buffer[4096];
memset(buffer, 0, sizeof(buffer));
fgets(buffer, sizeof(buffer) - 1, stdin);
if (buffer[0] == '\n') {
/* ループを抜け、トップメニューへ */
flag = 1;
break;
}
sscanf(buffer, "%s", inAdd->names);
----------------------------------------------------------------------
のような処理にしてしまいますが、どうでしょう。
ご回答ありがとうございます。
>extern Address *w_pt;// 何??
ですが、mallocで確保したメモリの解放時に使用しているので、ここでは不必要でした。
必要の無いものまで一緒に貼り付けてしまい申し訳ございませんでした。
>●本当は、どのような動作を期待していましたか?
ファイルから読み込んだデータに、入力したデータが追加されていくイメージです。
データの入力を
top_pt->next = inAdd;
inAdd->prev = top_pt;
inAdd->next = NULL;
のようにしてもうまくいかなかったんですが、これもおかしいでしょうか?
>のような処理にしてしまいますが、どうでしょう。
参考にさせていただきます。
本当にありがとうございました。
No.1
- 回答日時:
とりあえずヒントだけ。
>構造体の中身を表示させたところ、
>ファイルの最終データと、入力したデータのみになってしまいました。
>なぜなのか分かりません・・・。
ファイルの読み込みと、キー入力でリストの接続処理が違う理由は何でしょうか?
入力がファイルかキーボードかが違うだけでやることは一緒ですよ。
>また、データ登録の際に名前の入力に「gets」を使用しているんですが、
>「scanf」だとその次のif文が効かないみたいで少し困っています。
scanf()で取り込まれている内容がどうなっているのか、確認してみましょう。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- リフォーム・リノベーション 壁紙について 5 2022/10/19 12:09
- 工学 計器用変成器(PT/CT)を用いた電力測定方法について 2 2022/08/16 11:09
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- Gmail チャットGPTの登録ができない 1 2023/03/07 02:43
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- Excel(エクセル) Excelでなぜこのような式をつかっているのでしょうか、行に1,2,3と連番を振るだけなのに 5 2023/04/08 20:00
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バッファとは何ですか
-
VBA バイナリ―から文字列にす...
-
EXCEL VBAでテキストファイルの...
-
bitmap画像の保存がうまくいき...
-
【Teraterm】filewritelnについて
-
読み込んだファイル
-
Microsoft VBAで2GBを超えるフ...
-
BMP 仕様
-
C言語でBMPファイルの内容を表...
-
バイナリエディタのつかいかた
-
バイナリファイルの比較につい...
-
バイナリを16進数で表示したい
-
画像の保存方法。
-
= (イコール)で始まるセルの値...
-
【MFC】CFileでSeekした位置か...
-
入力ファイルをバイナリにする利点
-
Javaでのエンディアン変換
-
Excelファイルの軽量化の方法を...
-
双方向リストへのデータ登録
-
ページ読み込み時に自動的にsub...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッファとは何ですか
-
Microsoft VBAで2GBを超えるフ...
-
EXCEL VBAでテキストファイルの...
-
エクセルVBA 2千万行のCSVファ...
-
VBA バイナリ―から文字列にす...
-
ページ読み込み時に自動的にsub...
-
【python】Excelファイルを読み...
-
エラー:ストリームの終わりを...
-
EOF
-
テキストデータをSQLServerに取...
-
MacからWinにファイルを添付す...
-
バイナリエディタのつかいかた
-
リストビュー ⇔ 別ファイル構...
-
入力ファイルをバイナリにする利点
-
24ビットのWaveデータの中身に...
-
FTPでエクセルをPUTするとファ...
-
VB2010 COMポートからのバイナ...
-
バイナリ形式のXMLファイルを読...
-
JavaScriptの実行速度が遅い
-
バッファサイズについて
おすすめ情報