int型変数aとbにそれぞれ値を入力し、それらをかけた結果を出力するプログラムをつくりました。もし文字が入力されたら yarinaoshi と表示し再びaに値を入力するように指示します。しかしこのプログラムはデバグしても何のエラーもないのですが、実際に実行し文字を入力すると Microsoft C++ Debug Library というダイアログボックスが出てきて Abort, Retry, Ignore の三つのボタンがでてきます。どれを選んでも作業は止まってしまい、思ったような結果が得られません。一体どうすればいいのでしょうか?
以下がそのプログラムのソースコードです。
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int kakezan(int a, int b);
int main(void)
{
int dt= 1;
int a, b;
while(dt !=0){
printf("Int1:");
scanf("%d", &a);
if(isalpha(a) != 0)
{
printf("yarinaoshi");
scanf("%d", &a);
}
printf("Int2:");
scanf("%d", &b);
dt = kakezan(a, b);
printf("Result:%d\n", dt);
}
return 0;
}
int kakezan(int a, int b)
{
int dt;
return dt = a*b;
}
No.6ベストアンサー
- 回答日時:
このプログラムはBASIC言語風に捉えているようですね。
プログラムの流れはOKですよ。自信を持って良いと思います。ただ、CがBASIC言語と違うのは型に厳しいことです。たとえば、「if(isalpha(a) != 0)」のaは、確かにint型なのですが、整数の int型ではなく文字列の int型です。Cはそこは許してくれません。実行時の不合理なプログラムの動きは、scanf() 関数にあると考えます。多分、他のCを学んでいる人もこの問題に悩んでいるのではないでしょうか。解決は fgets()関数を使うことです。入力の訂正にバックスペース・キーが使えるので scanf() と違和感はないと思います。一応、入力関数 input_int() を載せておきますので、動かなかったプログラムと何処が違うのか比較していただけたらと思います。一応 Mac OSX では動きますので試して下さい。
/* Sample program with input() by Mac OSX
* file name: shom.c
* compile: gcc shom.c
* execution: ./a.out
*/
#include <stdio.h>
#include <stdlib.h>/* atoi() */
#define BUFF_SIZE32
#define ERR_COMMENT"Try again!!"
void input_int(char *, int *);
int kakezan(int, int);
int main(void) {
int dt;
int a, b;
/* 出題と同じにしてあります */
do {
input_int("Int1: val=", &a);
input_int("Int2: val=", &b);
dt = kakezan(a, b);
printf("Result:%d\n", dt);
} while (dt != 0);
return 0;
}
void input_int(char *comment, int *hensu) {
char buff[BUFF_SIZE], *temp;
intc, flag;
do {
printf("%s", comment);
temp = fgets(buff, BUFF_SIZE, stdin);
/* 末尾の \n を削除 */
while (*temp !='\0') temp++;
*(--temp) ='\0';
/* スペースと最初のマイナス符号を許容 */
temp = buff;
while (*temp == ' ') temp++;
if (*temp == '-') temp++;
/* 数字のみOK */
while ((c = *temp++) != '\0') {
flag = (c >= '0' && c <= '9') ? 0 : -1;
if (flag != 0) {
printf("\t\"%s\"?? %s\n", buff, ERR_COMMENT);
break;
}
}
} while (flag != 0);
*hensu = atoi(buff);
}
int kakezan(int a, int b) {
int dt;
return dt = a*b;
}
参考URL:http://www9.plala.or.jp/sgwr-t/c/sec07.html
ありがとうございます。いただいたソースコードを実行してみたところ自分の希望通りに動作しました。Cの世界は奥が深いですね。まだまだ知らない関数がいっぱいありました。これからもっと勉強していきたいと思います。
No.4
- 回答日時:
#1です。
見やすいように、タブの代わりに全角スペースを入れていますので、全部を半角スペース2個に置き換えてコンパイルしてみて下さい。
この回答への補足
半角スペース置き換えてコンパイルしたらエラーは無くなりました。しかし、実際入力のとき困ったことが起こります。最初に数字を入力してenterキーを押しても yarinaoshi が出てきます。そのあと何を入力しても yarinaoshi が表示され無限ループになってしまいす。一応全く同じソースコードを打ち込んだつもりですが、もしミスがあったら教えてください。以下がそのソースコードです。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int inputnum(char *);
int kakezan(int a, int b);
int main(void){
int dt = 1;
int a, b;
while(dt != 0){
a = inputnum("Int1:");
b = inputnum("Int2:");
dt = kakezan(a, b);
printf("Result:%d\n", dt);
}
return 0;
}
int inputnum(char *outstr){
char buf[256];
int ilp, iflg;
int iret;
for(;;){
iflg = 0;
printf("%s", outstr);
gets(buf);
for(ilp = 0; buf[ilp] != '\n'; ilp++){
if(!isdigit((unsigned char)buf[ilp])){
iflg = 1;
break;
}
}
if(iflg){
printf("yarinaoshi\n");
continue;
}
iret = atoi(buf);
break;
}
return iret;
}
int kakezan(int a, int b)
{
int dt;
return dt = a*b;
}
No.3
- 回答日時:
こんにちは。
C言語を始めて使ったときは、scanfに苦労しました。(汗)
すでに回答されている方がおりますが、私なりの補足です。
○scanf( 書式, 入力値の保存先 );
この関数では、入力した値を書式に従い変換し、入力値保存先に
設定します。
しかし、書式にあった入力しないと、この関数以降で入力値チェッ
クするどころか、この関数内で強制終了させられます。
○回避策
回答された方のソースを見ていただくと、「文字列として受け取り、
数値に変換」の流れとなり、結局はこのロジックをコーディングす
ることになります。
○参考例
同じ結果を求めても、人それぞれ表現が異なります。
私的には以下な感じです。(関数化等の詳細は省きます。)
#include <stdio.h>
#define INPUT_AREA_SIZE 511
#define INPUT_AREA_SIZE_SZ INPUT_AREA_SIZE+1
char str[ INPUT_AREA_SIZE_SZ ];
int num;
/* ここで、str変数を初期化 */
fgets( str, INPUT_AREA_SIZE, stdin );
/* ここで、str の内容をチェック (A)*/
num = atoi( str ); /* 文字列 → 数値 */
printf( "結果=%d\n" , num );
fflush( stdin ); /* 入力文字数超過分を消去 */
補足1:(A)に「数字以外のチェックと桁数」を組み込んで下さい。
補足2:gets関数を使う方法もありますが、入力文字数を超過する
とこの関数内で強制終了されますのでご注意を。
補足3:stdinは、予約語です。
○新入社員時代の先輩からの教え
「scanf関数関係は使うな~」でした。
一時的な利用であれば良いのですが、長期的な利用の場合は、時限
爆弾となる為です。
No.1
- 回答日時:
あまりにC言語に不慣れなのが丸分かりしてしまい、助太刀します。
scanf関数の一応の使い方は問題ないのですが、これでは数値のみの入力を前提としています。
したがって、文字を入力して文字かどうか判断する事は出来ないのです。
http://ja.wikipedia.org/wiki/Scanf
ちなみに同じ目的のプログラムを私が作った場合は以下のようにします。(文句は飛んできそうですが。。。)
---------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int inputnum(char *);
int kakezan(int a, int b);
int main(void)
{
int dt= 1;
int a, b;
while(dt != 0){
a = inputnum("Int1:");
b = inputnum("Int2:");
dt = kakezan(a, b);
printf("Result:%d\n", dt);
}
return 0;
}
int inputnum(char *outstr)
{
char buf[256];
int ilp,iflg;
int iret;
for(;;) {
iflg = 0;
printf("%s" ,outstr);
gets(buf);
for(ilp = 0 ; buf[ilp] != '\0' ; ilp++) {
if(!isdigit((unsigned char)buf[ilp])){
iflg = 1;
break;
}
}
if(iflg) {
printf("yarinaoshi\n");
continue;
}
iret = atoi(buf);
break;
}
return iret;
}
int kakezan(int a, int b)
{
int dt;
return dt = a*b;
}
この回答への補足
記述していただいたソースコードを実際そのままコピーしてデバグしたのですが、大量にエラーが出ていました。 エラーの内容はsyntax error, undeclared identifier, unicode identifiers are not yet supported, identifiler not found even with argument-dependent lookup, fatal error です。一文字も逃さないようにコピーしているのですが、何度やってもやはりエラーが出てきます。失礼ですがソースコードのどこかが間違ってはいないでしょうか?それともこちらの処理系に問題があるのでしょうか? 私はVC++2003を使っています。
補足日時:2010/01/06 14:38お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
(int *)の意味
-
C言語 エラーの原因がわからな...
-
【C++】関数ポインタの使い方
-
複数桁10進数の*桁目だけを抽出...
-
ゴールドバッハの予想のプログラム
-
ラップ関数とはどんなものですか?
-
比較回数と交換回数表示について
-
if と配列の組み合わせ
-
プログラムがうまく動作しない
-
newの使い方について。
-
剰余演算を論理演算と加減算に...
-
C#の質問
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 等差数列問題
-
アスタリスクで正方形
-
卒業研究でよく分からないとこ...
-
「{ } で囲むだけ」は正しい?
-
acceptをalarmでタイムアウトさ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
C言語 エラーの原因がわからな...
-
c++でテンプレートのコードでわ...
-
(int *)の意味
-
ラップ関数とはどんなものですか?
-
数字列を3桁ごとにカンマで区切...
-
c言語のリダイレクトによる円...
-
比較回数と交換回数表示について
-
実数の整数部,小数部の取得
-
if と配列の組み合わせ
-
構造体の勉強中です 合計点の高...
-
PowerShellがうまくいかない
-
c言語の配列を使ってサイコロを...
-
課題でつまってます・・・
-
C言語のサイコロシミュレート
-
エラー 添字が付けられた値が、...
おすすめ情報