質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

587閲覧

循環・重連結リスト switchを使った名前の探索が正常に動作しない

yuma1919

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2023/03/06 12:00

編集2023/03/06 13:38

前提

サッカー選手の得点ランキングを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; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2023/03/06 12:25

このままではコードが読みづらいので、質問を編集し、</>(コードの挿入)ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
thkana

2023/03/06 12:44

https://teratail.com/questions/utbomql8inoww0 で付いたコメントには対応する気がないということでしょうか... CとC++は別の言語です。 また、タグはあなたの投稿に注目を集めるためにあるのではなく、他の人が情報を検索しやすくするためにあるものです。余計な情報を含めないでください。
yuma1919

2023/03/06 13:40

コメントありがとうございます。 最近このサイトを使い始めたばかりで使い方がいまいちわかっていませんでした。 申し訳ありませんでした。 編集いたしましたのでご確認いただければ幸いです。
jimbe

2023/03/06 16:21 編集

scanf で文字列を取る場合は "%s" で良いのでは。 また、 main 内にずらずら処理を並べるのではなく、 (append のように ) 処理を関数化して分けたほうが良いと思います。
yuma1919

2023/03/06 16:30

コメントありがとうございます! %sにしたらなぜかうまくいきました! ありがとうございます!
jimbe

2023/03/06 18:48 編集

"%[^\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> が残ります。
yuma1919

2023/03/06 22:48

私の細かな疑問にも対応してくださりありがとうございました! とてもわかりやすく解説していただき疑問が解決しました! これからももっとcの理解を深めていきたいと思います。 ありがとうございました!
episteme

2023/03/07 03:43

解決したんなら"適切"にcloseしてください。
jimbe

2023/03/07 07:50

回答に書けば良かったですね。 コピペしときます。
yuma1919

2023/03/07 08:09

すみませんありがとうございます!
guest

回答1

0

ベストアンサー

scanf で文字列を取る場合は "%s" で良いのでは。


"%[^\n]%*c" はスペースを含む文字列を得るために使われますが、 他の scanf と組み合わせて使う場合は注意が必要です。
scanf はホワイトスペースを区切りとして標準入力から得ますが、区切りとして認識したホワイトスペース自体は残します。
改行は通常はホワイトスペース扱いであり、 %d や %s ではホワイトスペース以外を対象とするため対象の前に改行が有っても無視しますが、 "%[^\n]%*c" はその改行を無視しない為、空文字列の入力として処理してしまいます。

例えば
<space>123<enter><space>ABC<space><enter>
という標準入力を

c

1scanf("%d",&i); //int i 2scanf("%[^\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> が残ります。

投稿2023/03/07 07:51

編集2023/03/07 07:53
jimbe

総合スコア12639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問