• ベストアンサー

コマンドライン引数について。

コマンドライン引数についての質問です。 コマンドライン引数に適当な数字をいれ、金種別にわけるプログラムですが、 コマンドライン引数に負の値や、文字列を入力したときにはエラーが表示させるようにしているのですが、 数字と文字を混合したもののときはエラーが表示されずにそのまま処理されてしまいます。 初めの一文字目が数字だったらそのあとに文字を入れても実行されてしまうようです。 全て数字の場合のみ実行させてそれ以外はエラーメッセージを表示させたいのですが、どのようにすればいいでしょうか? #include <stdio.h> #include <stdlib.h> int syubetu(int money,int *kinsyu); int *kinsyu; int main(int argc,char *argv[]) { int *p,a; p=(int*)malloc(sizeof(int)*9); if(p==NULL){ printf("メモリ確保失敗\n"); exit(1); } a=atoi(argv[1]); if(a>0){ syubetu(a,&p[0]); printf("1万円 %d枚\n",p[0]); printf("5千円 %d枚\n",p[1]); printf(" 千円 %d枚\n",p[2]); printf("5百円 %d枚\n",p[3]); printf(" 百円 %d枚\n",p[4]); printf("50円 %d枚\n",p[5]); printf("10円 %d枚\n",p[6]); printf(" 5円 %d枚\n",p[7]); printf(" 1円 %d枚\n",p[8]); } else{ printf("入力エラー\n"); exit(1); } } int syubetu(int money,int *kinsyu) 800字以上になるため、処理は省略します。

質問者が選んだベストアンサー

  • ベストアンサー
  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.6

#3です。 >それを試したのですが、期待通りの結果になりませんでした。 >う~ん、なぜでしょう。 失礼! タイプミスがあったようです。 以下をコンパイル、実行してみてください。 #include <stdio.h> #include <stdlib.h> int isnumstr(char *s) { int c; while(c=*s++){ if((c<'0') || ('9'<c)) return(0); } return(1); } void main(int argc, char *argv[]) { int num; if(argc < 2) { printf("No args!\n"); exit(1); } num = atoi(argv[1]); printf("argv[1]=[%s], num=[%d]\n", argv[1], num); if(isnumstr(argv[1])) printf(" OK!\n"); else printf(" NG!\n"); }

usui323
質問者

お礼

実行できました! これを元にしてがんばろうとおもいます。 回答ありがとうございました。

その他の回答 (5)

  • bikkuri
  • ベストアンサー率33% (23/68)
回答No.5

文字を指定してもエラーにならないのは、atoiの仕様のためです。 atoiは数値として有効なところまでしか、解析せず、エラーも報告しません。 例として、 123A -> 123を返す 1A2 -> 1 A12 -> 0 という具合です。 実際の改善方法は#2さんのやり方に一票ですが、 課題としての扱いなら、自前で数字以外が含まれるかを 判定するのもいいのかも。 蛇足ながら、結果の格納先をmallocしてますが、 プログラム内容を見る限りでは、mallocの必要性はなく、単純に、 int p[9]; ... syubetu(a, &p[0]); /* or syubetu(a, p); */ でOKですよ。

usui323
質問者

お礼

回答ありがとうございます。 そうですね、mallocする必要はないですね。 ご指摘ありがとうございました。

  • arukamun
  • ベストアンサー率35% (842/2394)
回答No.4

こん**は atoiを使っているから、aにはint型の値しか入ってきませんね。 a=atoi(argv[1]); の代わりに、判定プログラムを書けば良いですね。 型宣言はあらかじめしておいてください。 int i ; if ( argc > 1 ){   a = 0 ;   i = 0 ;   while ( argv[1][i] != '\0' && argv[1][i] >= '0' && argv[1][i] <= '9' && a*10+argv[1][i]-'0' > a ){     a *= 10 ;     a += argv[1][i]-'0' ;     i++ ;   }   if ( argv[1][i] != '\0' ){     printf("入力エラー : ");     if ( argv[1][i] < '0' || argv[1][i] > '9' ){       printf("文字が含まれています。");     } else {       printf("int型を超えています。");     }     exit(1);   } } else {   printf("引数が足りません");   exit(1); } とか、適当なものを作れば良いですね。 がんばってください。

usui323
質問者

お礼

回答ありがとうございます。 前回の処理の部分に引き続きありがとうございます。 えーっと、まずwhileの所は一体なにをやっている処理なのでしょうか? argv[1][i]なんて初めて見ました。 これはどういう意味なのでしょう??? あとint型を超えるというのはどういう意味でしょうか?

  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.3

>全て数字の場合のみ実行させてそれ以外はエラーメッセージを表示させたい それなら、文字列が数字のみかどうかをチェックすればOKです。 具体的には次のような関数を作って呼び出し判定します。 /* 全てが0~9のとき1、それ以外が含まれるとき0を返す */ int isnumstr(cahr *s) {  int c;  while(c=*s++){   if((c<'0') || ('9'<c))    retuen(0)  }  return(1); }

usui323
質問者

お礼

回答ありがとうございます。 それを試したのですが、期待通りの結果になりませんでした。 う~ん、なぜでしょう。

noname#5537
noname#5537
回答No.2

atoi より strtol のほうが高機能です。(詳細は参考 URL) char *endptr; long x; x = strtol("123abc", &endptr, 10); if (*endptr != '\0') {  puts("だめ!"); } これに加えて, strtol に渡す文字列が空でないこと, strtol の戻り値が「LONG_MAX または LONG_MIN」でないこと, int の範囲に収まっていること,を確認しておけばよいでしょう。 あと,そこまでやるなら,argc のチェックもしておいたほうがいいと思います。 (argc !=2 だったらメッセージを出すとか。)

参考URL:
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_crt_strtol.2c_.wcstol.asp
usui323
質問者

お礼

回答ありがとうござます。 なんか授業でならった所までで出来るらしいので 聞いたことの無いstrtolは使わないでおこうと思います。

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.1

>int main(int argc,char *argv[]) と、char 型で扱っているせいではないですか? xxxxx 12 xxxxx 1-1 と入力されても、"1"しか受け取れないと思います。 string 型で受け取って、数値かどうかチェックするするのが普通では?

usui323
質問者

お礼

回答ありがとうございます。

関連するQ&A

専門家に質問してみよう