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

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

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

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

Q&A

解決済

3回答

3176閲覧

C言語:scanfで10桁の整数のみを受付ける方法

aluminium

総合スコア7

C

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

0グッド

0クリップ

投稿2020/08/12 19:33

初心者の学生です。どうぞ宜しくお願いいたします。

電話番号を入力するプログラムの課題を解いています。
10桁の数字以外(ハイフン等)が入力された場合にエラーを返す処理を書いたつもりですが、上手く動きません。
バッファーのような気がしているのですが、どうクリアしたら良いかわからず質問させていただきました。

お知恵をお借りできれば幸いです。お時間ありがとうございます。

出力画面

※変数の値を確認のため表示しており、見づらくて申し訳ありません

1回目は意図した動きをしています。
イメージ説明

1回目にハイフン入りの入力をすると、再入力時に正しく入力しても正常に処理してくれません。
イメージ説明

該当のソースコード

C

1#include <stdio.h> 2#include <string.h> 3#include <ctype.h> 4 5void clearKeyboard(void) 6{ 7 while (getchar() != '\n'); // バッファークリア 8} 9 10int main() 11{ 12 char phoneNum[11]; 13 int needInput = 1; 14 char *p = phoneNum; 15 int flg = 0; 16 17 printf("10桁の整数を入力してください: "); 18 while(needInput == 1) 19 { 20 scanf("%[^\n]", phoneNum); 21 clearKeyboard(); 22 while(*p) 23 { 24 if(!isdigit(*p++)) // phoneNumが 整数じゃなかったら フラグ付与 25 { 26 flg = 1; 27 } 28 } 29 if(flg || strlen(phoneNum) != 10) // phoneNumが整数じゃない or phoneNumが10桁じゃなかったら実行 30 { 31 needInput = 1; 32 printf("10桁の整数のみを入力してください: (needInput:%d, flg:%d, phoneNum:%s)", needInput, flg, phoneNum); 33 } 34 else 35 { 36 needInput = 0; 37 printf("10桁の整数が入力されました (needInput:%d, flg:%d, phoneNum:%s)", needInput, flg, phoneNum); 38 } 39} 40 return 0; 41}

試したこと

  • scanf の %10s を %12s にしたりした(結果変わりませんでした)
  • clearKeyboard 関数をエラーメッセージの後に入れた(再入力時に改行されてしまいました)

補足情報

このサイトでコンパイルしました。
https://www.onlinegdb.com/online_c_compiler

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

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

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

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

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

guest

回答3

0

scanfを使わずに、fgetsで1行の文字列として取り込み、文字操作により数字と桁数のチェックを行いましょう。

投稿2020/08/12 21:57

y_waiwai

総合スコア88042

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

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

aluminium

2020/08/13 04:07

fgetsという方法があるのですね! 学校の課題でscanfが必須でして... 今後fgetsを使えるように勉強します。 ありがとうございました!
guest

0

ベストアンサー

pの値が、最初にchar *p = phoneNum;で初期化された後、
while(*p)のループの中でp++され、その後、放置されています。
その為、二週目以降のwhile(*p)のループでは、前回ポインタを進めた場所からの開始となります。
結果、おそらくまともな値にはならず、整数ではないと判断され、flg = 1;が実行されます。
flg = 1;の時点で、if(flg || strlen(phoneNum) != 10)は、真となり、
needInput = 1;が実行されてループは継続されます。

while(*p)の前にp = phoneNum;として、ポインタの位置を戻してやると良いかと思います。


それはそれとして、数字だけを受け取りたいのであれば、
scanf("%[^\n]", buf);で一行すべて受け取った後に、
sscanf(buf,"%[0-9]",phoneNum);とかして、先頭からの連続した数字だけを読み取り、
if(strlen(phoneNum) != 10) とかで桁数だけをチェックでOKな気もします。
(一つも合致しなかったときの為にsscanfの戻り値のチェックも必要かな)

投稿2020/08/12 19:48

編集2020/08/12 20:02
amiya

総合スコア1218

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

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

aluminium

2020/08/13 04:07

scanfでの方法をご教示いただき かつ 最初にご回答くださりありがとうございます! "%[0-9]" で意図した処理になり、無事、課題を提出することができました。 ありがとうございました!
guest

0

タイトルに「scanf で」とありますが、scanf を使わない方法を示します。

C

1#include <stdio.h> // fgets, printf 2#include <string.h> // memcpy 3#include <ctype.h> // isdigit 4 5int main(void) 6{ 7 char phoneNum[11] = ""; 8 char buf[256]; 9 10 printf("10桁の整数を入力してください: "); 11 while (fgets(buf, sizeof buf, stdin)) { 12 int i = 0; 13 while (i < 10 && isdigit(buf[i])) i++; 14 if (i == 10 && buf[i] == '\n') { 15 memcpy(phoneNum, buf, 10); 16 printf("10桁の整数が入力されました (phoneNum:%s)\n", phoneNum); 17 break; 18 } 19 printf("10桁の整数のみを入力してください: "); 20 } 21}

ひらがなや漢字などを入力する可能性がある場合は、
isdigit(buf[i])isdigit((unsigned char)buf[i]) に変更してください。

投稿2020/08/13 00:42

kazuma-s

総合スコア8224

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

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

aluminium

2020/08/13 04:08

isdigitを配列で使えるようにするには、ご教示いただいた様にインクリメントすればいいんですね! ありがとうございます。今後使ってみたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問