- ベストアンサー
C言語プログラミングで「コマンドラインから3つの整数を入力し、大きい順に並べる
C言語プログラミングで「コマンドラインから3つの整数を入力し、大きい順に並べるプログラムの作成」なのですが,どなたかわかる人はいらっしゃりますか? C言語初心者です. if else文を使って作成するのですが,整数の入力において、同じ数字を認める方法と認めない方法がありますが,両方教えていただけると助かります. 例えば 10、5、21の数字をコマンドラインから入力したときに 出力結果は21、10、5と並ぶ. 同じ数字を認めるとき、例えば 10、10、30と入力したとき出力結果は30、10、10となる 同じ数字を認めないときは、コマンドラインからの入力時に、もし同じ数字が入力されたらエラーメッセージを返して終了 といった具合です.どなたかお願い致します.
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
おしい! いいところまでいってるんですが... >if( a>b && b>=c) 重複をみとめるなら、a=b (>c)の場合があります。よって if ( a >=b && b >=c ) です。以下同様 > printf("a>b>c%c",a>b>c); まずはprintfの「書式」というのが解説書にあるはずです。その%cをみれば、「指定した文字コードを持つ文字」とあるはずです(言いまわしは違うでしょうが) 例えば、 printf("%c",65); だと、一般的なPCなら、ASCIIコード65番にあたる「A」という文字が表示されます。 その 文字コードにあたるのが a>b>c になります。 ちょっと話がそれますが、 a>b>cはC言語では(a>b)>cと解釈されます。 ( a>b )は a>bなら真を表わす1,そうでないなら偽を表わす 0 という数値になります。(a>b)>cはその0か1と cの値 とを比較して、 同様に1か0の値になります。よって、ここれでは、ASCIIコード0か1の文字が表示されることになります。これらは特殊なコードなので、画面にはなにも表示されていないように見えるかもしれません。 a,b,cのそれぞれの値を表示したいので、10進の整数に変換される「%d」を使います。値が3つあるので、3つ指定します printf("%d, %d, %d\n",a,b,c); 以下同様。 重複不可版ですが ・>=を>にする:重複が無いので=になることはありえない。 ・最後のelseを else if (c > b && b > a ) { printf("%d,%d,%d\n",c,b,a); } とする。 すると、どのifにも該当しない→どこかに=になっているものがあった、ということなので else { printf("同じ値があります%d,%d,%d\n",c,b,a); } となります。他に、これらのifにの前に重複チェックをいれてもいいです。その方法は考えてみてください。 あと細かいことを言えば > main(int argc,char *argv[]) main関数の型が指定されていません。デフォルトでintになるのですが、自分で指定しておいた方が無難です。(コンパイラによっては、指定しないとエラーになります) また、intを指定したら、終了の前に retrun 0; と戻り値を指定しましょう。 >a=atoi(argv[1]); //atoi関数 コマンドライン引数が足りなかった場合、致命的なエラーになる可能性が大きいです。argvを使うまえに、argcの値を確認して、数が足りているかどうかを調べるようにしましょう。例えば、今回なら if ( argc != 4 ) { printf("引数の数が違います\n"); return 1; } a=atoi(argv[1]); //atoi関数 というように
その他の回答 (5)
- anicicle
- ベストアンサー率36% (129/356)
- BLK314
- ベストアンサー率55% (84/152)
#include <stdio.h> #include <stdlib.h> #include <string.h> /* 配列の要素数を返すマクロ */ #define ARRAY_OF(ar) (sizeof((ar)) / sizeof ((ar)[0])) /* BOOL用識別子 */ #define TRUE 1 #define FALSE 0 /* 小数点文字列であるか否か判定する */ static int IsFloat(const char* str) { return (strchr(str, '.') == NULL); } /* 重複チェックを行う */ static int IsDuplicate(const int tbl[], int Count) { int i; for (i = 0; i < Count; i++) { int j; for (j = i + 1; j < Count; ++j) { if (tbl[i] == tbl[j]) return TRUE; } } return FALSE; } /* qsort()で用いる比較用関数 aがbより前ならば負の値 aとbが同じ位置なら0 aがbより後ろなら正の値を返す 今回は昇順に並べるので 上記を言い換えると a > bならば負の値 a == bなら0 a < bならば正の値を返す */ static int compare_int(const int *a, const int *b) { return *b - *a; } /* ソートする */ static void sort(int tbl[], int Count) { /* クイックソートによる実装 高々3個限定ではオーバースペックであるが 汎用性はある */ qsort(tbl, Count, sizeof(int), (int (*)(const void*, const void*))compare_int); } int main(int argc, char* argv[]) { int buf[3]; /* 整数3つの格納領域 */ int i; /* コマンドラインから3つの数字を指定する 先頭にプログラム名が入るのでコマンドラインから 4つ渡されなければエラー */ if (argc != 4) { printf ("整数を3つ指定してください。\n"); return 1; } /* 入力値を整数に変換し、領域に格納する */ for (i = 0; i < ARRAY_OF (buf); ++i) { /* argc[0]はプログラム名である 引数はargc[1]から開始されることに注意する */ int n = sscanf(argv[i + 1], "%d", &buf[i]); if (n <= 0) { printf ("整数を3つ指定してください。\n"); return 1; } /* 整数であるかチェックする いきなりatoi()を使うと"ABC"も"0"も0に変換される sscanf()で"ABC"の可能性を排除している */ if (!IsFloat(argv[i + 1])) { printf ("整数を3つ指定してください。\n"); return 1; } } #define _DUPLICATE_ERROR_ /* 重複をエラーとしない場合はこの行を削除する */ #ifdef _DUPLICATE_ERROR_ /* 重複があればエラーとする */ if (IsDuplicate(buf, ARRAY_OF (buf))) { printf ("重複しない整数を3つ指定してください。\n"); return 1; } #endif /* ソートを行う*/ sort(buf, ARRAY_OF (buf)); // 表示を行う for (i = 0; i < ARRAY_OF (buf); ++i) { printf("%d\n", buf[i]); } return 0; }
お礼
ありがとうございます. C言語プログラムを始めたばかりなので,BLK314の書かれたソースコードが理解できるまで,頑張りたいと思います.
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
Gcc on Mac OSX です。 期待に応えられるかどうかは、わかりませんが、同じ数字を認めないときは引数に ON を与えて実行するプログラム例です。 ./a.out ON 10 5 21 同じ数字を認めるときは引数に OFF を与えます。なお、引数の ON,OFF は大文字です。 ./a.out OFF 10 10 21 /* Gcc on Mac OSX */ #include <stdio.h> #include <stdlib.h> // atoi() #include <string.h> // strcmp() #define N 3 int main(int argc, char *argv[]) { int i, j, temp, dat[N]; char *flag; flag = argv[1]; if (argc != 5 || (strcmp(flag,"ON") != 0 && strcmp(flag,"OFF") != 0)) { printf("Parameter error.\n"); //printf("引数エラーです。\n"); return 1; } printf("Input data:\n\t"); //printf("入力データ:\n\t"); for (i = 2; i < argc; i++) { dat[i - 2] = atoi(argv[i]); printf("%d ", dat[i - 2]); } printf("\n"); if (strcmp(flag,"ON") == 0) { if (dat[0] == dat[1] || dat[1] == dat[2] || dat[2] == dat[0]) { printf("Same value error.\n"); //printf("同じ数値は認められません。\n"); return 1; } } /* バブルソート */ for (i = 0; i < N; i++) { for (j = N - 1; j > i; j--) { if (dat[j - 1] < dat[j]) { temp = dat[j]; dat[j] = dat[j - 1]; dat[j - 1]= temp; } } } printf("Result:\n\t"); //printf("ソート結果:\n\t"); for (i = 0; i < N; i++) printf("%d ", dat[i]); printf("\n"); return 0; }
- kmee
- ベストアンサー率55% (1857/3366)
まずは、あなたが何がわかって、なにがわからないかはっきりさせましょう。 問題を分解すれば次のようになるかと思います。 ・コマンドラインから文字列を受け取る方法 (その時、引数が3つかどうか判定する方法) ・文字列を数値(整数)に変換する方法 ・'3つの数値を順番に並び換える方法 (いろんな方法があるが、今回はif/elseだけを使って、と条件が指定されている) ・(重複を認めない場合)重複しているかの判定方法 前2つは、教科書なり参考書なりをよく読みなおせば、必ず載っています、 後2つは、ちょっとした数学パズルです。 a,b,cの3つの数があったとして、 ・並び方は何通り? ・例えば、a,b,cの順に並ぶのは、それぞれの大小関係がどうなっているときかと言えば a≦b かつ b≦c ですよね。これらの不等式からa≦cはあきらかですし。 では、a.c.bだったら?他の組み合わせはどうでしょうか? ・a,b,cに重複する数がある、っていうのは、どんな場合? というのを、まず、数式や日本語(あなたがわかりやすければ英語でもフランス語でもいいですが)で表してみましょう。 あとは、それをC言語に「翻訳」するだけです。
補足
kmeeさん 私は最初,a,b,cという文字を利用して, #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> main(int argc,char *argv[]) { int i; int a,b,c; //int型変数a,b,c a=atoi(argv[1]); //atoi関数 b=atoi(argv[2]); //atoi関数 c=atoi(argv[3]); //atoi関数 for(i=0; i<argc; i++) { printf("argv[%d]=%s\n",i,argv[i]); } if(a>b&&b>=c) { printf("a>b>c%c",a>b>c); } else if(a>c&&c>=b) { printf("a>c>b%c",a>c>b); } else if(b>a&&a>=c) { printf("b>a>c%c",b>a>c); } else if(b>c&&c>=a) { printf("b>c>a%c",b>c>a); } else if(c>a&&a>=b) { printf("c>a>b%c",c>a>b); } else { printf("c>b>a%c",c>b>a); } } のようにプログラミングしました. しかし,これでは 「10、5、21の数字をコマンドラインから入力したときに 出力結果は21、10、5と並ぶ.」といった結果が返ってきません. よろしくお願い致します.
- Tacosan
- ベストアンサー率23% (3656/15482)
「コマンドラインから入力する」とはどういう意味でしょうか? そして, あなたはどこが分からないというのですか? あなたなら, 3つの整数を与えられたときにどのようにして「大きい順に並べる」のですか?
お礼
申し訳ございません.質問の内容がわかりづらかったですね. なんとかこの問題を解くことができました.ありがとうございました.
お礼
以後気をつけます