プロが教える店舗&オフィスのセキュリティ対策術

C言語プログラミングで「コマンドラインから3つの整数を入力し、大きい順に並べるプログラムの作成」なのですが,どなたかわかる人はいらっしゃりますか?

C言語初心者です.


if else文を使って作成するのですが,整数の入力において、同じ数字を認める方法と認めない方法がありますが,両方教えていただけると助かります.

例えば
10、5、21の数字をコマンドラインから入力したときに 出力結果は21、10、5と並ぶ.

同じ数字を認めるとき、例えば 10、10、30と入力したとき出力結果は30、10、10となる

同じ数字を認めないときは、コマンドラインからの入力時に、もし同じ数字が入力されたらエラーメッセージを返して終了

といった具合です.どなたかお願い致します.

A 回答 (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関数
というように
    • good
    • 0

こんなのがありました。


http://detail.chiebukuro.yahoo.co.jp/qa/question …
    • good
    • 0
この回答へのお礼

以後気をつけます

お礼日時:2010/03/28 18:36

#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;
}
    • good
    • 1
この回答へのお礼

ありがとうございます.
C言語プログラムを始めたばかりなので,BLK314の書かれたソースコードが理解できるまで,頑張りたいと思います.

お礼日時:2010/03/28 21:50

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;
}
    • good
    • 0

まずは、あなたが何がわかって、なにがわからないかはっきりさせましょう。



問題を分解すれば次のようになるかと思います。
・コマンドラインから文字列を受け取る方法
(その時、引数が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と並ぶ.」といった結果が返ってきません.
よろしくお願い致します.

補足日時:2010/03/28 13:35
    • good
    • 0

「コマンドラインから入力する」とはどういう意味でしょうか?


そして, あなたはどこが分からないというのですか?
あなたなら, 3つの整数を与えられたときにどのようにして「大きい順に並べる」のですか?
    • good
    • 0
この回答へのお礼

申し訳ございません.質問の内容がわかりづらかったですね.
なんとかこの問題を解くことができました.ありがとうございました.

お礼日時:2010/03/28 21:46

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!