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

このQ&Aに関連する最新のQ&A

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に関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語で作成したプログラムの、エコーバックをなくしたい…。

現在、SolarisでC言語の簡単なアプリケーションを作成しています。
そこで、管理者以外の人に悪用されないようにという名目で、作ったプログラムを端末エミュレータで起動させ、それに標準入力からパスワードを入力させるようにしたいと考えています。
しかし、そのためには、入力したパスワードをターミナル上に表示されては困るので、ターミナルに入力された文字列を表示させないようにするにはどうしたらよいのでしょうか?
いろいろと調べたのですが、具体的な関数がよくわからなかったので、エコーバックをなくすような関数がありましたら、是非教えてただきたいと思います。

Aベストアンサー

結構、面倒です。覚悟してください。入出力がファイルにリダイレクトされている場合の処置とか、途中でCtrl+Cを押された場合の始末とか、諸々を付け加えると100ステップを超えてしまうかもしれません。

#include <termio.h>
struct termio tbuf;
char passowrd [100];
ioctl (0, TCGETA, &tbuf);
tbuf.c_lflag &= ~ECHO;
ioctl (0, TCSETA, &tbuf);
fputs ("password: ", stdout);
fgets (password, stdin);
tbuf.c_lflag |= ECHO;
ioctl (0,TCSETA, &tbuf);

QC言語で簡単なゲームを作る方法

僕はC言語を学び始めた程度ですが、一番簡単に作れるゲームとその作り方(ソース)を教えて下さい。お願いします。

Aベストアンサー

★じゃんけんゲームのソースです。

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

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP_KATI : TYP_MAKE);
  case JKN_CHOKI:  return ((computer == JKN_PA) ? TYP_KATI : TYP_MAKE);
  case JKN_PA:  return ((computer == JKN_GOO) ? TYP_KATI : TYP_MAKE);
  default:   return -1;
 }
}

// じゃんけんゲーム
int main( void )
{
 // ゲーム変数
 int count;  // 勝負回数
 int kati = 0; // 勝ちカウンタ
 int make = 0; // 負けカウンタ
 // 一時変数
 int human;  // キー入力の一時変数(人間用)
 int computer; // 乱数発生の一時変数(コンピュータ用)
 
 // (6)じゃんけん勝負を10回行う
 printf( "★じゃんけんゲーム(10回勝負)\n\n" );
 for ( count = 1 ; count <= 10 ; count++ ){
  // (1)人間:3つの状態を入力
  printf( "%2d回目…[1]グー [2]チョキ [3]パー を入力して下さい:", count );
  do {
   // (2)キー入力
   switch ( getche() ){
    case '1': human = JKN_GOO; break;
    case '2': human = JKN_CHOKI; break;
    case '3': human = JKN_PA; break;
    default: human = -1; break;
   }
  } while ( human == -1 );
  
  // (3)コンピュータ:3つの状態を乱数で決める
  computer = (rand() % 3);
  // (4)人間vsコンピュータの勝負
  switch ( check(human,computer) ){
   case TYP_KATI:
    kati++;
    printf( "⇒勝ち。\n" );
    break;
   case TYP_MAKE:
    make++;
    printf( "⇒負け。\n" );
    break;
   case TYP_AIKO:
    printf( "⇒引き分け。\n" );
    break;
   default:
    printf( "⇒エラー。\n" );
    break;
  }
 }
 // (7)結果表示
 printf( "\n★じゃんけんゲームの結果\n" );
 printf( "人間    :%d 回勝ち\n", kati );
 printf( "コンピュータ:%d 回勝ち\n", make );
 printf( "※引き分け回数は %d 回でした。\n", (10 - kati - make) );
 return 0;
}

注意:全角空白をタブ文字に変換して下さい。

★じゃんけんゲームのソースです。

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

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP...続きを読む

QC言語 While文(ループ)内の文字入力

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }

   return 0;
}

【実行結果(キーボードからは「 e 」と入力」)】
1文字を入力:e
入力したのは e です。
1文字を入力:入力したのは
です。
1文字を入力:

【私が意図している結果】
1文字を入力:e
入力したのは e です。
1文字を入力:


 ちなみにC言語の環境は、インターネットで無料で入手できる試食版です。(LSI C-86 Ver3.30c 試食版)
 上記プログラムを見てもらえればお分かりだと思いますが、「xを入力するまで、永遠と1文字入力とその表示を行う」ことを意図しています。しかし実際の結果は意図に反しています。
 1回目は正常に動作しているようですが、問題は2回目以降。scnafで入力待ちをすることなく、なぜかscanfをスルーする形で3回目のscanf入力待ちとなっています。この理由を教えてください。お願いします。

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。

【プログラム部分】
#include<stdio.h>

int main(void)
{
   char a;

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);

   if(a == ...続きを読む

Aベストアンサー

>1文字を入力:入力したのは
>です。

は、[Enter]キーの入力によるためです。
[Enter]キーをスルーする必要があります。

   char a;
char dummy; /*[Enter]キー用*/

   while(1)
   {
   printf("1文字を入力:");
   scanf("%c",&a);
scanf("%c",&dummy); /*[Enter]キー用*/

   if(a == 'x')
     break;

   printf("入力したのは %c です。\n",a);
   }


で、どうでしょうか?

Qif文の中にfor文なのか、for文の中にif文なのか

for文の中に分岐を作って計算するのと、if文を先に書いてからfor文にするのとではどちらが一般的ですか?

for ( i = 0; i < n; i++)
{
if ( a > b ) {
y = i;
} else {
y = i * 2;
}
printf( "%d", y );
}

とするか、

if ( a > b ) {
for ( i = 0; i < n; i++)
{
y = i;
}
} else {
for ( i = 0; i < n; i++)
{
y = i * 2;
}
}
printf( "%d", y );

とするかという事です。
ちなみにプログラムは適当ですのでちょっとしたミスはご勘弁ください。

個人的には後者の方が分岐が少ない分負担は減ると思うのですが、前者の方がすっきりとしているのでこちらを使いたいのです。

もちろん、微々たる差なので好きな方を使えという意見もあると思いますが、皆さんはどちらを使いますか?

for文の中に分岐を作って計算するのと、if文を先に書いてからfor文にするのとではどちらが一般的ですか?

for ( i = 0; i < n; i++)
{
if ( a > b ) {
y = i;
} else {
y = i * 2;
}
printf( "%d", y );
}

とするか、

if ( a > b ) {
for ( i = 0; i < n; i++)
{
y = i;
}
} else {
for ( i = 0; i < n; i++)
{
y = i * 2;
}
}
printf( "%d", y );

とするかという事です。
ちなみにプログラムは適当で...続きを読む

Aベストアンサー

基本は、「同じ(ほとんど同じ)ものが複数存在すると、必ず矛盾が発生する」という言葉に集約できるかなと思います。
後者の場合、i < n じゃなくて、i <= n だったなんていうときにどちらか一方の修正を漏らして、なおかつ、テストで、片方のループしか検証できていなかったなどということは起こりがちです。

また、コンパイラやコンピュータの負担が多い少ないは、本当にそれを考えなければならいほどシビアなときだけ気にすればOKです。
たいていの場合、最近のコンパイラは、普通のプログラマよりよっぽどうまく最適化をしてくれたりしますし。

あと、条件を整える → 実行する という2段階もありです。
この例だと、

int scale = (a > b) ? 1 : 2;
for(i = 0; i < n; i++)
{
y = i * scale;
}
printf( "%d", y );

たとえば、こんな感じ。

Q1秒は何ミリ秒とか、単位変換の問題が苦手です。

今ITパスポートなどの情報処理技術者試験などの勉強をしているのですが、
1秒は何ミリ秒とか、3,600,000ミリ秒は何時間とかの単位変換の問題が苦手です。

また、4,096バイトは何kバイトとかの単位変換の問題とかも苦手です。
どのようにしたら、早く正確に解くことできるようになるでしょうか?

答え間違っていたり、答えが正解してても時間がかかってしまったりします。

計算方法や早く正確に解く方法など、教えていただけないでしょうか?

よろしくお願いします。

Aベストアンサー

基本的には慣れの問題だと思いますが・・・。

あとは下記のことを覚えるぐらいでしょうか。

■ 一般的に使われる1000の倍数の単位を覚える
1K = 1000
1M = 1K × 1000
1G = 1M × 1000
1T = 1G × 1000
1m = 1 ÷ 1000
1μ = 1m ÷ 1000
1n = 1μ ÷ 1000
http://ja.wikipedia.org/wiki/SI%E6%8E%A5%E9%A0%AD%E8%BE%9E


■ 2は10乗すると約1000(1024 = 1K)になる


■ 2の10乗までの数は暗記する
 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024

 計算が楽になります。
 例えば、2の5乗だったら、「2,4,8,16,32」と(心の中で)数えながら、指を折っていけば32が求まります。片手の指を全部折って開けば1024になるはずですから、そうならなければどこかで間違えた事になります。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング