こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

大学の授業で作った暗号化プログラムが動きません。

下記のような暗号化プログラムを作成したのですが動きません。
問題のある場所は36行目(/で囲まれた行)で式の構文エラーと診断されたのですが、どう直せばいいのか分かりません。
どなたかどうすればよいのかお教え下さい。

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

int anngou (int c, char b[81])
{
while (c <= 81) {
if(b[c] >= 'a' && b[c] <= 'z') {
if(b[c] >= 'a' && b[c] <= 'm') {
b[c] = b[c] + 13;
} else {
b[c] = b[c] - 13;
}
} else {
if(b[c] >= 'A' && b[c] <= 'Z') {
if(b[c] >= 'A' && b[c] <= 'M') {
b[c] = b[c] + 13;
}else{
b[c] = b[c] - 13;
}
}
}
}
return b[c];
}

int main(void)
{
int a, c;
char b[81];

a = c = 0;
while (a <= 9) {
printf("Input some words: ");
fgets(b, 81, stdin);
/b[c] = anngou(char b[c]);/
c = 0;
while (c <= 81) {
printf("%s", b[c]);
c++;
}
printf("\n");
a++;
}
exit(0);
}

投稿日時 - 2009-07-20 14:36:11

QNo.5140575

すぐに回答ほしいです

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

《重要な欠陥》
暗号化対象の「入力文字列の長さ」について、なんら考慮されていない。
改行コードを含めちょうど80文字の時であっても、while( c <= 81 ){ は不適切。

 http://www.bohyoh.com/CandCPP/C/Library/fgets.html 参照(「読み取る文字数の最大値は n - 1 とする」)

>問題のある場所は36行目(/で囲まれた行)で、式の構文エラーと診断されたのですが、どう直せばいいのか分かりません。

 1:他の行には問題が無く、「設計」を見直す必要はない、として。

  ・main 関数は、b[c] = anngou( b[c] ); となっています(ケアレスミス修正済)。

    「型」で書くと、(char) = anngou( (char) ); 「1文字渡して、1文字受け取る」

  ・このことから、全文字を暗号化するためには、全文字分(*)をループさせる必要があります。

  ・よって、2ステップ後の while 構文の先頭に、移動する必要があります。
  ・なお、while 構文中の printf( "%s", b[c] ); は1文字ずつ( b[c] )出力なので、"%s" は "%c" です。

  ・anngou() 関数は、int anngou( int c, char b[81] ) となっています。

    これを、呼び出し元(「1文字渡して、1文字受け取る」)に合わせるには、char anngou( char cOne ) とし、
    全ての b[c] という記述を、cOne とする必要があります( c でも d でも e でもいいんだが)。
    もちろん、while( c <= 81 ){ は不要です(1文字だけなのでループの必要なし)。

  *:「全文字分」の判定は、fgets() で入力するので、while 文は、while( '\n' != b[ c ] ){ です。

  これで動作します。

 結果、たったこれだけのプログラムにも「問題のある場所は」山ほどあって、★Cコンパイラって不親切だなぁ、★「設計」って大事だな、と判ったかと・・。

 2:<ctype.h> これは、「文字種を判定」するために・・ですよね。
   使わなくていいの?。

 3:「設計」を見直し、「 anngou() 関数は、1回の呼び出しで全文字分を暗号化する」としてみたら如何でしょう。

   No.3 さんのを、ちょこっと・・・、(前出)while 文は、whi・・・。

投稿日時 - 2009-07-20 18:51:19

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

Cプログラミングの基本的な理解ができていないようなので、基本から勉強しなおしましょう。
やりたいのは、下記のようなことかな?

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

void anngou (char b[])
{
int c;
c = 0;
while (b[c]) {
if(b[c] >= 'a' && b[c] <= 'z') {
if(b[c] >= 'a' && b[c] <= 'm') {
b[c] = b[c] + 13;
} else {
b[c] = b[c] - 13;
}
} else {
if(b[c] >= 'A' && b[c] <= 'Z') {
if(b[c] >= 'A' && b[c] <= 'M') {
b[c] = b[c] + 13;
}else{
b[c] = b[c] - 13;
}
}
}
c++;
}
}

int main(void)
{
int a;
char b[81];

a = 0;
while (a <= 9) {
printf("Input some words: ");
fgets(b, 81, stdin);
anngou(b);
printf("%s\n", b);
a++;
}
}

投稿日時 - 2009-07-20 17:20:49

ANo.2

問題点が二つあります。
ひとつは文法的なもの、もうひとつは暗号化を行う関数の中身です。

まず文法面では、コンパイルエラーになるのは関数の定義
int anngou (int c, char b[81])
と呼び出し方
b[c] = anngou(char b[c]);
が合っていないからです。関数の定義にしたがえば、引数は int型の変数1個と、char型の配列1個ですから文法的には
anngou( c, b );
のような書き方になります。

続いて、この暗号化を行う関数の中身ですが、何をしたいのかよくわかりません。c <= 81 の間は無限ループになっており、プログラムが終わりません。

治療方法ですが、まずこの暗号化関数 anngou の仕様を定義しましょう。
テンプレートを示しますので、これを埋めてください。

/**
 関数 anngou
 概要 (ここに関数の概要を一言で説明する。)

 入力引数 int c    (この変数の意味)
      char b[81]  (この変数の意味)
 出力引数 (必要に応じて)
 戻り値 (returnで何か返す場合、その値の意味)

 備考 (特に注意を必要とすることや参考資料の在り処など)
*/

一般的に、行儀のよいソースコードは関数の本体の前にこのようなコメント文をつけて、その関数がどのようなものか分かるように書かれています。

投稿日時 - 2009-07-20 17:18:56

補足

エラーの方は消えました。ありがとうございます。
c <= 81 の間が無限ループになるということなので22行目と23行目の間に、c++; を追加したのですが無限ループしているのかプログラムが進みません。
どうすればよいのか教えていただけないでしょうか?

投稿日時 - 2009-07-21 23:17:58

ANo.1

b[c] = anngou(char b[c]);
で、関数呼び出しの際に変数定義している。
最初に定義したanngou()とは引数の数が違う
anngou()の定義の中に型定義以外のものが含まれている([81]のところ)

プログラムの中身については見ていません。

投稿日時 - 2009-07-20 14:42:35

補足

anngou()の定義の中に型定義以外のものが含まれている([81]のところ)
この問題を解決するにはどうしたらよいのでしょうか?
それと、指摘された残り二つの問題は
b[c] = anngou(int c, char[81]);
と書き換えることで解決できているのでしょうか?

投稿日時 - 2009-07-20 16:25:47

あなたにオススメの質問