前提
サッカー選手の得点ランキングを10位まで表示、探索、削除するなどの処理を行う
ランキングで人物の探索はできるが、名前を使っての探索が動作はするもののうまくいかない。
scanfを使っているがまず名前を打たせてくれない
発生している問題・エラーメッセージ
caseの2、4が正常に動作しない
該当のソースコード
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct __Soccercheck { char name[256]; int Ranking; int Uniform; int age; int Number; int Games; struct __Soccercheck *next; struct __Soccercheck *prev; } Soccercheck; Soccercheck *append(Soccercheck *tail, const char *name, int rank, int uni, int age, int num, int game) { Soccercheck *x = malloc(sizeof(Soccercheck)); strcpy(x->name, name); x->Ranking = rank; x->Uniform = uni; x->age = age; x->Number = num; x->Games = game; x->next = tail->next; x->prev = tail; tail->next->prev = x; tail->next = x; tail = tail->next; return tail; } int main(void) { Soccercheck *dommy = (Soccercheck *)malloc(sizeof(Soccercheck)); Soccercheck *head = dommy; Soccercheck *tail = dommy; dommy->next = dommy; dommy->prev = dommy; tail = append(tail, "モハメド・サラー", 1, 11, 29, 23, 35); tail = append(tail, "ソン・フンミン", 1, 7, 29, 23, 35); tail = append(tail, "クリスティアーノ・ロナウド", 3, 7, 37, 18, 30); tail = append(tail, "ハリー・ケーン", 4, 10, 28, 17, 37); tail = append(tail, "サディオ・マネ", 5, 10, 30, 16, 34); tail = append(tail, "ディエゴ・ジョッタ", 6, 20, 25, 15, 35); tail = append(tail, "ケヴィン・デ・ブライネ", 6, 17, 30, 15, 30); tail = append(tail, "ジェイミー・ヴァーディ", 6, 9, 35, 15, 25); tail = append(tail, "ウィルフリード・ザハ", 9, 11, 29, 14, 33); tail = append(tail, "ラヒム・スターリング", 10, 7, 27, 13, 30); int num = 0; Soccercheck *tmp = head->next; while (1) { printf("どのような操作をしますか?\n 1:一覧表字、2:検索(名前), 3:検索(ランキング), 4:削除, 5:終了 ->"); scanf("%d", &num); switch (num) { case 1: // 一覧表字 tmp = head->next; while (1) { printf("選手名%s, サッカープレミアリーグ得点ランキング%d, 背番号%d, 年齢%d, ゴール数%d, 出場試合数%d\n", tmp->name, tmp->Ranking, tmp->Uniform, tmp->age, tmp->Number, tmp->Games); tmp = tmp->next; if (tmp == head) break; } break; case 2: // 名前検索 { char seek[10000]; printf("誰のことを知りたいですか?:"); scanf("%[^\n]%*c", seek); tmp = head->next; while (1) { if (strcmp(tmp->name, seek) == 0) { printf("選手名%s, サッカープレミアリーグ得点ランキング%d, 背番号%d, 年齢%d, ゴール数%d, 出場試合数%d\n", tmp->name, tmp->Ranking, tmp->Uniform, tmp->age, tmp->Number, tmp->Games); break; } tmp = tmp->next; if (tmp == head) { printf("\n%sさんのデータは見つかりませんでした。", seek); break; } } } break; case 3: // ランキング検索 { int rank = 0; printf("\n何位の人を知りたいですか?"); scanf("%d", &rank); tmp = head->next; while (1) { if (tmp->Ranking == rank) { printf("選手名%s, サッカープレミアリーグ得点ランキング%d, 背番号%d, 年齢%d, ゴール数%d, 出場試合数%d\n", tmp->name, tmp->Ranking, tmp->Uniform, tmp->age, tmp->Number, tmp->Games); break; } tmp = tmp->next; if (tmp == head) { printf("\n%d位の人のデータは見つかりませんでした。", rank); break; } } } break; case 4: // データの削除 { char erase[10000]; printf("\n誰のデータを削除しますか?: "); scanf("%[^\n]%*c", erase); printf("%sさんのデータを削除します。\n", erase); tmp = head->next; while (1) { if (strcmp(tmp->name, erase) == 0) { tmp->prev->next = tmp->next; tmp->next->prev = tmp->prev; free(tmp); break; } tmp = tmp->next; if (tmp == head) { printf("\n%sさんのデータは見つかりませんでした。", erase); break; } } } break; default: printf("正しい数字を入れてください\n"); continue; } break; } return 0; }
このままではコードが読みづらいので、質問を編集し、</>(コードの挿入)ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
https://teratail.com/questions/utbomql8inoww0
で付いたコメントには対応する気がないということでしょうか...
CとC++は別の言語です。
また、タグはあなたの投稿に注目を集めるためにあるのではなく、他の人が情報を検索しやすくするためにあるものです。余計な情報を含めないでください。
コメントありがとうございます。
最近このサイトを使い始めたばかりで使い方がいまいちわかっていませんでした。
申し訳ありませんでした。
編集いたしましたのでご確認いただければ幸いです。
scanf で文字列を取る場合は "%s" で良いのでは。
また、 main 内にずらずら処理を並べるのではなく、 (append のように ) 処理を関数化して分けたほうが良いと思います。
コメントありがとうございます!
%sにしたらなぜかうまくいきました!
ありがとうございます!
"%[^\n]%*c" はスペースを含む文字列を得るために使われますが、 他の scanf と組み合わせて使う場合は注意が必要です。
scanf はホワイトスペースを区切りとして標準入力から得ますが、区切りとして認識したホワイトスペース自体は残します。
改行は通常はホワイトスペース扱いであり、 %d や %s ではホワイトスペース以外を対象とするため対象の前に改行が有っても無視しますが、 "%[^\n]%*c" はその改行を無視しない為、空文字列の入力として処理してしまいます。
例えば
<space>123<enter><space>ABC<space><enter>
という標準入力を
scanf("%d",&i); //int i
scanf("%[^\n]%*c",s); //char s[N];
で処理した場合、
1つ目の scanf で <space> がホワイトスペースとして無視、"123" が処理されて i が 123 になり、2つ目の scanf で 123 の後ろの <enter> が処理されて s が "" になり、標準入力には <space>ABC<space><enter> が残ります。
もし 2つ目が scanf("%s",s) だったら、 123 の後ろの <enter> と ABC の前の <space> はホワイトスペースとして無視、 "ABC" が処理されて s は "ABC" となり、標準入力には <space><enter> が残ります。
私の細かな疑問にも対応してくださりありがとうございました!
とてもわかりやすく解説していただき疑問が解決しました!
これからももっとcの理解を深めていきたいと思います。
ありがとうございました!
解決したんなら"適切"にcloseしてください。
回答に書けば良かったですね。
コピペしときます。
すみませんありがとうございます!
回答1件
あなたの回答
tips
プレビュー