ダイクストラ法を利用した最短経路問題のプログラムを書いています。
構造体をつくり、メンバ配列として、つながっている先のノードを格納する配列と、そのコストを格納する配列を作成しました。
配列のサイズをすべてのノード数-1に設定し、配列の要素についてはキーボードからの入力値にしたいと考えています。
ノードは必ずしも残りのすべてのノードにつながっているわけではなく、2つだったり3つだったりすると思います。よって、キーボードから受ける入力数が必ずしも要素数-1だけあるとは限らないと思います。
しかし、キーボードからの入力scanfは、入力される数を決めなければいけません。(scanf("%d",&x,&y)のように)
そこで質問させていただきたいことは、
scanfで入力される数を決めない(ユーザー側に任せる)ことはできるのでしょうか?
もしできなければ、if文等を使って、要素数より少ない入力数だったら、breakするなど条件分岐をする必要があるのでしょうか?
よろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
個人的にはfgets()好みですがw、
ループで0が入力されるとか、終了条件を設定して複数回scanf()を使えば良いのでは?
数値に限りますが・・・
投稿2020/07/26 02:33
総合スコア6851
0
scanfは、書式指定に従って値を取得してそれを第2以降の引数に与えられたポインタの場所に格納します。
取得の終了は、
・変換に失敗したとき
・指定された変換を完了したとき
です。その意味では、
キーボードからの入力scanfは、入力される数を決めなければいけません。
もちろん書式指定は無限には続けられませんから、取得するデータの最大個数は決めなければいけませんが、敢えて途中で変換が失敗するようなデータを与えれば変換に成功した分だけのデータの個数を返り値としてscanf関数の動作を終了します。
例えば、double型の変数a,b,cがあったとして
scanf("%lf%lf%lf",&a,&b,&c);
に対して
1 2 a
というデータをあたえてやれば、aは浮動小数点数に変換が出来ませんから1をaに、2をbに取得しただけでscanf関数は終了し、変換に成功したデータの個数2を返します。
なお、変換に失敗した文字は標準入力に戻されますから、
scanf("%lf%lf%lf",&a,&b,&c);
に1 2 aを与えた直後に再度
scanf("%lf%lf%lf",&a,&b,&c);
を実行したならば、標準入力の先頭はaになっていますから2度めのscanfは全て変換失敗で0を返すことになります。
もし続けてデータの取得を行いたいなら、何らかの方法で標準入力に残っている'a'を取り除かなければいけません。この辺は、あり得るパターンをいろいろ考え出すとキリがないので入力の仕方で制約するなどとしないと収拾がつかなくなりますけれど。
投稿2020/07/26 03:23
総合スコア7703
0
scanf
を使う場合、一項目ずつ読み込むというかたちにすることで要望をかなえることができると思います。以下のコードは、空白で区切られた文字列をEOFが出現するまでひたすら読み出すコードです。
C
1#include <stdio.h> 2 3int main() { 4 char buf[256]; 5 int num = 0; 6 7 for (;;) { 8 int ret = scanf("%s", buf); 9 if (ret == 1) { 10 /* 正しく1つ分、入力された */ 11 ++num; 12 printf("%d: %s\n", num, buf); 13 } else if (ret == EOF) { 14 /* EOFなので入力終了 */ 15 break; 16 } 17 } 18 19 printf("\ndone. num=%d\n", num); 20 return 0; 21}
このプログラムを実行してみます。
sh
1 2$ gcc -Wall -o t1 t1.c 3$ ./t1 4item1 51: item1 6item2 item3 72: item2 83: item3 9item4 item5 item6 item7 104: item4 115: item5 126: item6 137: item7 14item8 158: item8 16item9 item10 179: item9 1810: item10 19 20done. num=10 21$
データを格納したテキストファイルをあらかじめ用意して、標準入力のリダイレクトを利用して実行した例です。(こちらの方が何が起こっているか分かりやすいかもしれません)
sh
1$ cat data.txt 2item1 3item2 item3 4item4 item5 item6 item7 5item8 item9 6item10 7$ ./t1 < data.txt 81: item1 92: item2 103: item3 114: item4 125: item5 136: item6 147: item7 158: item8 169: item9 1710: item10 18 19done. num=10
データが文字列であったり数値であったりする場合は、データの出現順に合わせて適時、atoi
やstrtol
などの標準関数を利用して変換処理を行う必要があるでしょう。
その他、AtCoderなどの競技プログラミングでは標準入力で外部データの取り込みをすることが多いので、そういった情報も併せて検索してみると多くのヒントが得られるかとも思います。
投稿2020/07/26 02:55
総合スコア9256
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/26 09:50
2020/07/26 10:05
2020/07/26 11:56
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/26 09:42