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

C言語で以下のプログラムを作らなくてはなりません。
どなたかご教授くださるようお願いいたします。

1 入力された値を階乗するプログラム
<表示>
  値を入力してください。

  答え:XXXXX

2 パスワード作成ツール
<使用方法>
  ./mypasswd [user ID][パスワード文字数]

<機能>
  下記の条件にあった任意の文字列を標準出力に返す。
条件1 引数[user ID]は必須
条件2 指定できる出力文字列は6,7,8文字のいずれかとする(省略可、デフォルト8文字)
条件3 出力もじる津を構成する文字列範囲はa~z、A~Z、0~9とする。
条件4 ユーザーアカウントに含まれる文字列を含まない。
条件5 英大文字を最低1文字含む。
条件6 英小文字を最低1文字含む。
条件7 数字を1文字含む。

<設計>
  下記の関数を組み合わせる。
関数1 引数チェック関数(条件1、2)
関数2 ヘルプを表示する関数(条件1、2、の説明文を表示する)
関数3 時刻を種にした乱数を用いて、任意の1文字を返す関数
関数4 ある1文字が使用可能文字列に含まれるものかどうかを判断する関数(条件3)
関数5 ある1文字が、userIDに含まれるものかどうかを判断する関数(条件4)
関数6 関数3~5を利用して、パスワ-ドに使用することが出来る文字列を返す関数
関数7 関数6を利用し、条件5~7が考慮された文字列を返す関数

3 入力された計算式を計算するプログラムを作成

<機能>
  +-*/(括弧は使用しない)の組合せで小数も扱う。
  敷の最大長は100文字までとする。

<表示>
  計算式を入力してください。

  答え:XXXXXXXXXX

A 回答 (9件)

・・・では、続きいきます。



>関数3 時刻を種にした乱数を用いて、任意の1文字を返す関数
関数:char GetRandomChar(void)
仕様:略(上の文で十分)
実装:以下のURLの「プログラム例」を参考にしてください。rand()の戻り値はintなので%256を忘れないように。
http://www.microsoft.com/japan/developer/library …

>関数4 ある1文字が使用可能文字列に含まれるものかどうかを判断する関数(条件3)
関数、仕様、実装:略。isalnum()を使用する。

>関数5 ある1文字が、userIDに含まれるものかどうかを判断する関数(条件4)
条件4では文字列となっていますが?とりあえず、userIDとパスワードの間に共通する文字がない、という条件と解釈します。
関数、仕様、実装:略。strchr()の結果がNULLか否かで文字の重複を確認する。

>関数6 関数3~5を利用して、パスワ-ドに使用することが出来る文字列を返す関数
関数:void GetPassword(int nLength, char* pszUseID, char* pszPassword)
仕様:(未検査の)パスワードを作成し、pszPasswordに格納する
実装:(1)whileによるループ(継続条件はループカウント<nLength)。その中で関数3による文字の取得→関数4および5によるチェック(失格したならcontinue)→文字をpszPassword[(ループカウント)]に書き込む→ループカウント+1、を行う。
(2)出来上がったpszPasswordの最後に'\0'を付加して関数終了。

>関数7 関数6を利用し、条件5~7が考慮された文字列を返す関数
関数:void GetPasswordChecked(int nLength, char* pszUseID, char* pszPassword)
仕様:検査済みパスワードをpszPasswordに取得する
実装:(1)数字の存在フラグ、小文字の存在フラグ、大文字の存在フラグを用意する。
(2)無限ループの中で各文字種の存在フラグをオフ→関数6→isdigit(),islouwer(),isupper()による文字のチェックをpszPasswordに対して実行(条件に一致したら対応する文字種の存在フラグをセット)→すべての文字種の存在フラグがオンならbreakを繰り返す。

・・・とこんなところでしょうか。
    • good
    • 0
この回答へのお礼

ご丁寧に分かりやすくご回答いただき、ありがとうございます。関数は大変参考になります。私はどの関数を使おうかと、いろいろな関数の仕様を調べながら、ノートに書いておいたのですが、hiromura様の関数の方が、とってもすっきりしていてすばらしいですね。私のほうは1つの条件をクリアする為に何個かの関数を組み合わせてしまったりして、あとで自分で読み直してみても、とてもややこしいく、読みづらいのです。プロの方が書くプログラムほど参考になるものはありませんね。ご回答いただいた関数を自分でもよく調べてみます。とても難しいですね。でも経験者の方にアドバイスしていただいたり、自分で調べたりして、問題が解決できれば最高にうれしいことですね。私も早く、このようなすばらしいプログラムが書けるようにがんばります。これからも何かありましたら、ご指導ください。よろしくお願い致します。

お礼日時:2002/01/17 12:27

>ちなみにこのようなプログラムはhitomura様のようなプロ(?)の方からみると、いかほどのレベルなのでしょうか?


>入門レベル、初心者レベル、中級者レベル、上級者レベルのどのあたりのレベルでしょうか?
>また、hitomura様はこのようなプログラムを大体どのくらいの時間で、ソースを書くことが出来ますでしょうか?
回答を名指しで指定されるのはありがたいのですが、私だけに尋ねるよりも、ほかの方々の意見もきいたほうがいいのではないでしょうか。

当初の質問とは関係のないことでもありますので、回答はいたしません。
新たに質問を作成されたなら、私見を述べさせていただきます。

ただし、「プログラムを作る」といっても、どの時点から開始するかということによって話が変わってきます。
「パスワード作成ツールを作る」と決めた時か、機能が決定した時か、関数の設計が確定した時かをはっきりしてください。
    • good
    • 0

ちょっと補足です。



>ご回答いただいた関数を自分でもよく調べてみます。(No.6のお礼より)
勘違いされるといけないので一言。関数4と関数5以外は自分で作成します。実装に書いたロジックで関数を記述していくわけです。

>関数5と条件4はユーザーIDに含まれている文字を含まないということです。(No.6のお礼より)
つまり、自分の書いた方法で合っていたわけですが、ひとつ質問です。
「"0123456789"というユーザーIDの人のパスワードはどうします?」
条件4によって数字はパスワードに使えなくなりますが、条件7によってパスワードには数字が最低1文字含まれなくてはなりません。

それと、乱数によって出力された文字が使用可能文字か&userIDに含まれていないか調べるよりも、最初からそういう条件で文字を乱数出力するほうがいいような気がします。

こちらは、グローバル領域に0-9,a-z,A-Zを並べた文字配列(文字列ではありません)を作成し、userIDに使用されている文字を配列の中から消去、その文字配列に残った文字の中からランダムに文字を選ぶ、という仕様にすればうまくいくと思います。
    • good
    • 0
この回答へのお礼

hiromura様、ご丁寧に補足してくださり、ありがとうございます。

>「"0123456789"というユーザーIDの人のパスワードはどうします?」
条件4によって数字はパスワードに使えなくなりますが、条件7によってパスワードには数字が最低1文字含まれなくてはなりません。

   そうですね。ではユーザーIDの文字だけを含めてはいけないということで
   数字は含めてもいいということでは難しいでしょうか?

>それと、乱数によって出力された文字が使用可能文字か&userIDに含まれていないか調べるよりも、最初からそういう条件で文字を乱数出力するほうがいいような気がします。

>こちらは、グローバル領域に0-9,a-z,A-Zを並べた文字配列(文字列ではありません)を作成し、userIDに使用されている文字を配列の中から消去、その文字配列に残った文字の中からランダムに文字を選ぶ、という仕様にすればうまくいくと思います。

   なるほど~。この方がずっとすっきりしてわかりやすいですね。とても合理   的だと思います。もう一度プログラム全体の設計を再検討してみます。
   ご指摘&アドバイスを頂き本当にありがとうございます。

ちなみにこのようなプログラムはhitomura様のようなプロ(?)の方からみると、いかほどのレベルなのでしょうか?入門レベル、初心者レベル、中級者レベル、上級者レベルのどのあたりのレベルでしょうか?また、hitomura様はこのようなプログラムを大体どのくらいの時間で、ソースを書くことが出来ますでしょうか?
お時間があるときにでも、御返事いただければ、大変嬉しく思います。

お礼日時:2002/01/18 00:07

…っと、ひとつだけ書き忘れていたことがあります。



それは、「プログラミングは、自分でプログラムを書いて上達する」ということです。

ヒント(と呼ぶには少々多すぎた気もしますが)は出しましたので、あとは頑張ってください。
    • good
    • 0
この回答へのお礼

このアドバイスを肝に銘じます。
自分で考えて、悩みに悩みぬいた上で経験あるかたにご質問しなければなりませんね。今度ご質問するときは自分でここまで書いてみた!!けれどもここがわからないというふうにソースをきちんと書いてご質問させていただきます。
本当にありがとうございました。

お礼日時:2002/01/17 13:15

> パスワード作成ツール


分からないのは何処でしょうか?
関数6ですか?全てですか?
問題を絞り込んで書かれた方がよいと思います。

後、関数5の仕様と、条件4が異なっていますが、どちらが正しいのでしょうか?>1文字と文字列
この部分が解けているのなら良いのですが

関数3ならrandとsrandとtimeを調べてみてください。
他は漠然としすぎていて、答えに困ります。

>入力された計算式を計算するプログラムを作成
演算子順位文法で検索してみてください。
小数無しのは昔書いたことがあるので、参考になるかも知れません
http://www.susono.com/~sohei/work/cpp/chap01.html
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。お礼が遅くなりまして申し訳ありません。
関数5と条件4はユーザーIDに含まれている文字を含まないということです。私自身がこのプログラムを作成するまで、実力が追いついていなくて、それぞれの条件を満たす関数はどれか考えながら、関数の使い方を勉強している段階です。
条件が多いので、それぞれの関数をどう組み合わせていけばいいのか、どのように設計していけばいいのか、混乱してしまっております。
計算式を計算するプログラムはリンク先を参考にさせていただきます。
現段階の私の力では難しいかもしれませんが、これを乗り越えなくてはいけませんね。これからも何かありましたら、よろしくお願い致します。

お礼日時:2002/01/17 12:14

>質問させていただいた2のパスワードを作成する


>プログラムは難しいでしょうか?
ではやってみましょうか(…ってissy-toさんではないのに。なんてでしゃばりなんだ>私)。
でも、これだけ仕様が確定しているなら簡単なので、ポイントだけ書くことにします。

>関数1 引数チェック関数(条件1、2)
関数:int CheckArgments(int nArgv, char** pszArgv)
仕様:main()の引数をそのまま受けとり、引数が条件1、2を満たしているなら1、いずれかが満たされていなければ0を返す。
実装:(1)nArgvの値をチェック
(2)pszArgv[2]の文字列長およびatoi()の結果をチェック

>関数2 ヘルプを表示する関数(条件1、2、の説明文を表示する)
関数:void ShowUsage(void)
仕様:プログラムの使用法を表示する。
実装:printf()文を並べるだけなので省略。
付記:プログラム名の表示を行うならば、ソースにその名称を書くよりも、argv[0]の文字列を使用したほうが良い。その場合は当関数の引数はchar* pszProgramNameとなる。

…すいません、ちょっと都合によりいったん書き込みを終了します。
    • good
    • 0

実行結果の5!の入力数値が0になっているのは気にしないで下さい。


0!のコピペですので。
    • good
    • 0

即席ですので参考程度に見てください。

(補足)
    • good
    • 0

こんなプログラムはどうでしょうか?



#include <stdio.h>
#include <stdlib.h>

int Factorial(x);

int main()
{
long i;
printf("******************************\n");
printf("* 階乗を計算するプログラム *\n");
printf("******************************\n\n");
printf("数値を入力してください--->");
scanf("%ld",&i);

printf("\n%ld!=%ld\n",i, Factorial(i));

exit(0);
}

int Factorial(x)
{
if(x == 0) return(1);
else return( Factorial(x-1)*x);
}

実行結果
******************************
* 階乗を計算するプログラム *
******************************

数値を入力してください--->0

0!=1

******************************
* 階乗を計算するプログラム *
******************************

数値を入力してください--->0

5!=120
    • good
    • 0
この回答へのお礼

さっそくのご回答ありがとうございました。
試してみます。Factorial関数大変参考になりました。
ちなみに、質問させていただいた2のパスワードを作成する
プログラムは難しいでしょうか?

お礼日時:2002/01/16 16:47

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