• ベストアンサー

C言語でパスワード作成ツール

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

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

  • ベストアンサー
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.6

・・・では、続きいきます。 >関数3 時刻を種にした乱数を用いて、任意の1文字を返す関数 関数:char GetRandomChar(void) 仕様:略(上の文で十分) 実装:以下のURLの「プログラム例」を参考にしてください。rand()の戻り値はintなので%256を忘れないように。 http://www.microsoft.com/japan/developer/library/default.asp?URL=/japan/developer/library/vccore/_crt_srand.htm >関数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を繰り返す。 ・・・とこんなところでしょうか。

kiroro302
質問者

お礼

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

その他の回答 (8)

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.9

>ちなみにこのようなプログラムはhitomura様のようなプロ(?)の方からみると、いかほどのレベルなのでしょうか? >入門レベル、初心者レベル、中級者レベル、上級者レベルのどのあたりのレベルでしょうか? >また、hitomura様はこのようなプログラムを大体どのくらいの時間で、ソースを書くことが出来ますでしょうか? 回答を名指しで指定されるのはありがたいのですが、私だけに尋ねるよりも、ほかの方々の意見もきいたほうがいいのではないでしょうか。 当初の質問とは関係のないことでもありますので、回答はいたしません。 新たに質問を作成されたなら、私見を述べさせていただきます。 ただし、「プログラムを作る」といっても、どの時点から開始するかということによって話が変わってきます。 「パスワード作成ツールを作る」と決めた時か、機能が決定した時か、関数の設計が確定した時かをはっきりしてください。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.8

ちょっと補足です。 >ご回答いただいた関数を自分でもよく調べてみます。(No.6のお礼より) 勘違いされるといけないので一言。関数4と関数5以外は自分で作成します。実装に書いたロジックで関数を記述していくわけです。 >関数5と条件4はユーザーIDに含まれている文字を含まないということです。(No.6のお礼より) つまり、自分の書いた方法で合っていたわけですが、ひとつ質問です。 「"0123456789"というユーザーIDの人のパスワードはどうします?」 条件4によって数字はパスワードに使えなくなりますが、条件7によってパスワードには数字が最低1文字含まれなくてはなりません。 それと、乱数によって出力された文字が使用可能文字か&userIDに含まれていないか調べるよりも、最初からそういう条件で文字を乱数出力するほうがいいような気がします。 こちらは、グローバル領域に0-9,a-z,A-Zを並べた文字配列(文字列ではありません)を作成し、userIDに使用されている文字を配列の中から消去、その文字配列に残った文字の中からランダムに文字を選ぶ、という仕様にすればうまくいくと思います。

kiroro302
質問者

お礼

hiromura様、ご丁寧に補足してくださり、ありがとうございます。 >「"0123456789"というユーザーIDの人のパスワードはどうします?」 条件4によって数字はパスワードに使えなくなりますが、条件7によってパスワードには数字が最低1文字含まれなくてはなりません。    そうですね。ではユーザーIDの文字だけを含めてはいけないということで    数字は含めてもいいということでは難しいでしょうか? >それと、乱数によって出力された文字が使用可能文字か&userIDに含まれていないか調べるよりも、最初からそういう条件で文字を乱数出力するほうがいいような気がします。 >こちらは、グローバル領域に0-9,a-z,A-Zを並べた文字配列(文字列ではありません)を作成し、userIDに使用されている文字を配列の中から消去、その文字配列に残った文字の中からランダムに文字を選ぶ、という仕様にすればうまくいくと思います。    なるほど~。この方がずっとすっきりしてわかりやすいですね。とても合理   的だと思います。もう一度プログラム全体の設計を再検討してみます。    ご指摘&アドバイスを頂き本当にありがとうございます。 ちなみにこのようなプログラムはhitomura様のようなプロ(?)の方からみると、いかほどのレベルなのでしょうか?入門レベル、初心者レベル、中級者レベル、上級者レベルのどのあたりのレベルでしょうか?また、hitomura様はこのようなプログラムを大体どのくらいの時間で、ソースを書くことが出来ますでしょうか? お時間があるときにでも、御返事いただければ、大変嬉しく思います。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.7

…っと、ひとつだけ書き忘れていたことがあります。 それは、「プログラミングは、自分でプログラムを書いて上達する」ということです。 ヒント(と呼ぶには少々多すぎた気もしますが)は出しましたので、あとは頑張ってください。

kiroro302
質問者

お礼

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

  • sssohei
  • ベストアンサー率33% (33/98)
回答No.5

> パスワード作成ツール 分からないのは何処でしょうか? 関数6ですか?全てですか? 問題を絞り込んで書かれた方がよいと思います。 後、関数5の仕様と、条件4が異なっていますが、どちらが正しいのでしょうか?>1文字と文字列 この部分が解けているのなら良いのですが 関数3ならrandとsrandとtimeを調べてみてください。 他は漠然としすぎていて、答えに困ります。 >入力された計算式を計算するプログラムを作成 演算子順位文法で検索してみてください。 小数無しのは昔書いたことがあるので、参考になるかも知れません http://www.susono.com/~sohei/work/cpp/chap01.html

kiroro302
質問者

お礼

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

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.4

>質問させていただいた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となる。 …すいません、ちょっと都合によりいったん書き込みを終了します。

  • issy-to
  • ベストアンサー率20% (1/5)
回答No.3

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

  • issy-to
  • ベストアンサー率20% (1/5)
回答No.2

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

  • issy-to
  • ベストアンサー率20% (1/5)
回答No.1

こんなプログラムはどうでしょうか? #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

kiroro302
質問者

お礼

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

関連するQ&A

  • C言語です。よろしくお願いします

    何をすればいいのかがさっぱりです 文字列を入力 入力された文字列について 次の(1)~(6)のすべてを表示するプログラムを作成 (1) 全文字の合計文字数 (2) 数字の文字数 (3) 英大文字の文字数 (4) 英小文字の文字数 (5) 空白の文字数 (6) その他の文字の文字数 データの読み込みはgetchar 関数を使用 実行例 total = (1) numeric= (2) large = (3) small = (4) space = (5) other = (1)-(2)(3)(4)(5) よろしくお願いします

  • C言語プログラミング

    [問題] 一行文字列を読み込み、その中の英小文字列をすべて英大文字に出力するプログラムを作りなさい。 という問題です。どなたか分かる方ご指導お願いします!

  • C言語

    以下のC言語のプログラムを教えてください。 お願いします。 (1)標準入力から文字列(2 文字以上)を入力し,文字数を計上すると共に,入力された文字列の逆順に入れ替える処理を実現してください.なお,以下の要件を満たしたプログラムを作成してください. ・ 入力された文字列は,char 型の配列(要素数50)で受け取ること ・ 文字数を計上するcount 関数(引数:配列のアドレス,戻り値:文字数)を定義 し,main 関数より呼び出すこと ・ 文字列を逆順に入れ替えるreverse 関数(引数:配列のアドレス,戻り値:無し) を定義し,main 関数より呼び出すこと ・ 標準出力の処理は,main 関数で記述すること 【プロトタイプ宣言】 int count(char *str); void reverse(char *str); 【実行結果】 文字列を入力してください(2 文字以上) apple 文字数 = 5 入れ換え前 apple 入れ換え後 elppa (2)char 型の配列(要素数50)を2 つ宣言し,標準入力から2 つの文字列を入力してください.そして,格納した字列を入れ替える関数(swapstr 関数)を作成し,入れ替え前と入れ替え後の配列内の値(文字列)を配列名とともに標準出力するプログラムを作成してください. 【プロトタイプ宣言】 void swapstr(char *str1, char *str2); 【実行結果】 2 つの文字列を入力してください apple strawberry 入れ換え前 配列str1 = apple 配列str2 = strawberry 入れ換え後 配列str1 = strawberry 配列str2 = apple

  • C言語の問題

    配列の問題 1.キーボードから入力したアルファベットの大文字(A~Z)の入力回数をそれぞれ数え、結果を画面出力するプログラムを作成せよ。但し、入力の終了はEOFとし、入力回数のカウントには、配列を用いるものとする。(文字ごとに回数を格納する配列を用意する) 2.キーボードから番号(数字)を入力し、その番号に該当する文字列中の文字を画面表示するプログラムを作成せよ。なお、数字以外の文字が入力した場合と、文字列の範囲外の数字が入力された場合は、任意のメッセージを出力し、再入力するようにする。また文字列はキーボードから入力するものとする。 この問題が解けなくて困ってます。どうか知恵をかしてください。

  • C言語についての質問です

    C言語についての質問です キーボードから文字列を入力しそれらを結合して行くことで長い文字列を作成する "Q"を入力した場合入力終了する "F"を入力した場合既存の文字列の前部に追加文字列を加える "R"を入力した場合既存の文字列の後部に追加文字列を追加する。 追加文字列はF,Q,Rのいずれかを入力したのちにキーボードより入力する。 またグローバル関数を使用しないでプログラムを作成する。加えてmain関数とは別に次の様な関数を作成し利用する 戻り値 : 無し(void型) 引数1 : コマンド文字列(Q,F,Rなどの追加文字列の追加場所を決定するchar型配列) 引数2 : 追加文字列(char配列) 引数3 : 追加される側の文字列(char配列) どうしてもグローバル関数を使用しないで作成することができません。また後部への追加文字列の追加はstrcat関数を使い実現することができましたが前部への追加文字列の追加の方法がわかりません。アドバイスやヒントなど何でもいいので指導のほどよろしくお願いします。

  • C言語

    (a) キーボードから入力された文字列をそのままディスプレイに表示するプログラムを作成しなさい。 という問題 #include<stdio.h> main() { char word[1000]; /*文字型の変数の宣言*/ scanf("%s", word); /*キーボードから文字列を入力*/ printf("%s\n", word); /*入力した文字列を出力*/ } と作りましたがこれではコンソール中で文字を打ってからエンターを押さないといけないからといわれ再提出になってしまいました。 エンターを押さないでそのまま出力するということは、できるのでしょうか? あと自分の作ったプログラムではスペースや改行を使うことができないから使えるようにしろと言われてましたがそれわできますか? 変換仕様をかえればいいのですか ほかにもかえる所はありますか?

  • C言語のプログラムです。

    次のようなプログラムを作成しようと考えています。 1.文字列を入力し、入力した文字列にアルファベット以外の文字が含まれていたら再入力。 2."end"もしくは"END"が入力されたらプログラム終了。 3.main関数とは別の関数で入力した文字列に現れる文字を全て入力順に大文字で表示する。(小文字と大文字は同じ文字として扱い、出現個数も合わせて表示する) ※2.では文字列を比較するstrcmpを使用。 表示結果例)  入力:DxbhzAeFSXY  出力:D=1,X=2,B=1,H=1,Z=1,A=1,E=1,F=1,S=1,Y=1 (応用)3.では入力順に表示させていたが、アルファベット順に結果を表示する。 上記の2.までのプログラムは作成できたのですが、3.及び応用が分からず大変困っています。 どなたかご教授ください。 #include <stdio.h> #include <string.h> int sub(int ss[i],int n){ int x; for(x=1; x<=n; x++){ //小文字を大文字に変換 if(ss[i]>=97){ ss[i]=ss[i]-32; } } } int main(void){ char ss[80]; char sa[2][4]={{\"end\"},{\"END\"}}; int a, i, n; int flag= 0; //アルファベット以外の入力があった際の判別 do{ printf(\"文字列を入力してください\\n\"); gets(ss); n= strlen(ss); //文字列ssの長さを求める if(n=3 && ((strncmp(ss,sa[0],3)==0)) || ((strncmp(ss,sa[1],3)==0))){ //endまたはENDの判定 return 0; } for(i=0; i<n; i++){ if((ss[i]>=65 && ss[i]<=90) || (ss[i]>=97 && ss[i]<=122)){ } else{ flag=1; break; } } }while(flag=1); }

  • c言語がわかりません

    (1)数学関数(cos)を用いて、10度から50度まで10度刻みのcos値の表を表示するプログラムを作成。 数学関数のヘッダファイル:<math.h> cos関数:cos(ラディアン値) (double型) ラディアン値 r=d*(3.14159/180) (2)文字列の大小比較を行なうstrcmp関数を用いて、入力された2つの文字列の大小比較を行い、結果を表示するプログラムを作成。 strcmp関数形:int strcmp(a,b) a,bは文字列(文字配列) 戻り値:a<bなら負、a=bなら0,a>bなら正

  • Visual C++の簡単なプログラムについて

    Visual C++で以下のようなプログラムまたは関数を作りたいのでアルゴリズムもしくはヒントを教えてください。 (1) 入力された文字列の文字数を算出するプログラム (2) 『abc』→『abcabc』のように引数として受け取った文字列を2回繰り返した文字列に変換する関数

  • C言語プログラミング

    文字列を入力して、1文字右に回転させて出力するプログラムを教えてください。 例 入力文字reste→出力結果ester

専門家に質問してみよう