• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:双方向リストへのデータ登録)

双方向リストへのデータ登録

このQ&Aのポイント
  • C言語を使って双方向リストへのデータ登録で問題が発生しています。
  • ファイルからのデータ読み込みは成功しているが、新しいデータの登録がうまくいかない。
  • データ登録の際に名前の入力に「gets」を使用しているが、次のif文が効かない。

質問者が選んだベストアンサー

  • ベストアンサー
  • Yanch
  • ベストアンサー率50% (114/225)
回答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()の組み合わせが有効な場合もあるかもしれません。

ya-cha
質問者

お礼

アドバイスありがとうございます。 関数化について考えてみたいと思います。 また、fgetsとsscanの組み合わせの有効的な使用方法は分かりませんので、とりあえず私の分かる範囲で処理を記述してみたいと思います。 色々アドバイスありがとうございました。

その他の回答 (8)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.8

標準に含まれているかどうかは, それこそ「標準を確認する」だけでわかるはずです. ANSI そのものには当たっていませんが, ISO や JIS の規格を調べれば「gets が標準に含まれている」ことは想像できるはずです. JIS なら http://www.jisc.go.jp/ の「JIS 検索」で規格番号として「X3010」を入れれば閲覧だけは出来ます. あと, この書き方では「最後にごみデータが入る」可能性があります. 「ファイルの末尾」のチェック方法によるもので, 実際に空のファイルを読み込ませてみれば簡単にわかるはず.

ya-cha
質問者

お礼

ありがとうございます。 また、ファイルの末尾のチェック方法についてですが、ループの途中に、fscanfとEOFを比較して、ループから抜けるようにしました。 ごみデータが入ってしまう事は私も分かっており、悩んでいたんですが、回答者様のご指摘を参考に上記処理にて解決できました。(正しい方法なのかは分かりませんが・・・) ありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

ああ, ついでにもう 1つですが, この 「ファイルからの読み込み」 のところは論理的にたぶん間違っています. この形で feof を使うのは危ない気がするなぁ.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

すみません, 「『scanf』はANSIC標準だけど、『gets』は違う」 という情報はどこにありますか? もちろん「gets は危険なので使うべきではない」というのはその通りだけど....

ya-cha
質問者

お礼

カーニハン/リッチーのANSIC規格準拠のプログラミング言語Cに「gets」関数が出てこないので、標準ではないのかと思っていますが、違いましたでしょうか? また、No7についてですが、理由が全く分かりません(泣) 何故なのか教えていただけないでしょうか?

  • Yanch
  • ベストアンサー率50% (114/225)
回答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); ---------------------------------------------------------------------- のような処理にしてしまいますが、どうでしょう。

ya-cha
質問者

お礼

ご回答ありがとうございます。 >extern Address *w_pt;// 何?? ですが、mallocで確保したメモリの解放時に使用しているので、ここでは不必要でした。 必要の無いものまで一緒に貼り付けてしまい申し訳ございませんでした。 >●本当は、どのような動作を期待していましたか? ファイルから読み込んだデータに、入力したデータが追加されていくイメージです。 データの入力を top_pt->next = inAdd; inAdd->prev = top_pt; inAdd->next = NULL; のようにしてもうまくいかなかったんですが、これもおかしいでしょうか? >のような処理にしてしまいますが、どうでしょう。 参考にさせていただきます。 本当にありがとうございました。

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.4

> 「scanf」だとその次のif文が効かないみたいで少し困っています。 > if(!*inAdd->names){ * は、どういった意味合いで付けていますか?

ya-cha
質問者

お礼

「構造体のデータ」です。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

すみません, できれば「出来れば ANSI C 標準の scanf を使いたい」の意味をお教えいただけますか? ひょっとして, 「ANSI C 標準でない scanf」もある?

ya-cha
質問者

お礼

「scanf」はANSIC標準だけど、「gets」は違うという意味で書いただけです。

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.2

せっかくソースコードを載せるのであれば、 回答者のところで「そのまま」コピー&ペーストして コンパイル&実行できるよう、 断片でなく全体を載せる方がよいと思いませんか? 載っていない部分を想像で補うことができないのです。

ya-cha
質問者

お礼

ご回答ありがとうございます。 全体が大きかったので、必要かなと思う箇所のみ貼り付けておりました。 申し訳ございません。

  • arain
  • ベストアンサー率27% (292/1049)
回答No.1

とりあえずヒントだけ。 >構造体の中身を表示させたところ、 >ファイルの最終データと、入力したデータのみになってしまいました。 >なぜなのか分かりません・・・。 ファイルの読み込みと、キー入力でリストの接続処理が違う理由は何でしょうか? 入力がファイルかキーボードかが違うだけでやることは一緒ですよ。 >また、データ登録の際に名前の入力に「gets」を使用しているんですが、 >「scanf」だとその次のif文が効かないみたいで少し困っています。 scanf()で取り込まれている内容がどうなっているのか、確認してみましょう。

ya-cha
質問者

お礼

ご回答ありがとうございます。

関連するQ&A