シーザー暗号について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
gyakusai
記事: 1
登録日時: 9年前

シーザー暗号について

#1

投稿記事 by gyakusai » 9年前

C言語のシーザー暗号についての質問です。

コマンドライン引数として、ファイル名、-d(復号化)又は-e (暗号化)、-n x(xはシフト量)、-f fname(読み込むファイルの名前、ない場合は標準入力で暗号化、または複合化したい文章を入力) を与え、暗号化、または複合化した文字列を返すプログラムを作りたいのですが修正をお願いいたします。ファイルに含まれる文字は全てアルファベットの大文字か小文字という前提です。文字をシフトするdo_shiftでポインタをうまく使えばよいとのことですが、わかりませんでした。また、ファイル名がない場合、標準入力をどのように実装すればいいかもよくわかっていません。 FILE *fp = stdin;ですでに実装されているのでしょうか?

コード:

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

 void do_shift(int direction, int shift , char buf[]){
 int len =0, i;

 len == strlen(buf);

 if(direction == 1){
 for(i=0; i<len; i++){
 buf[i] = tolower(buf[i]);
 if(buf[i] + shift <= 'z'){
 buf[i] += shift;
 }else{
 buf[i] += shift-26;
 }
 }
 }

 if(direction == -1){
 for(i=0; i<len ; i++){
 buf[i] = tolower(buf[i]);
 if(buf[i] - shift >= 'a'){
 buf[i] -= shift;
 }else{
 buf[i] -= shift+26;
 }
 }
 }

 }

 void convert (int direction, int shift, FILE *fp ) {
 char buf[10000];

 while( fgets (buf,10000,fp)) {
 do_shift(direction, shift ,buf);
 printf("%s",buf);
 }
 }


 int main(int argc, char *argv[]){
 int i=0, direction=0, shift=0;
 FILE *fp = stdin;
 char *fname=NULL;

 i = 1;
 while(i < argc){
 if (strcmp(argv[i], "-e") ==0){
 direction = 1;
 i += 1;
 }
 else if(strcmp(argv[i], "-d") ==0){
 direction = -1;
 i += 1;
 }
 else if(strcmp(argv[i], "-n") ==0){
 if(i + 1 <argc){
 shift = atoi(argv[i+1]);
 i += 2;
 }
 else {
 fprintf(stderr, "-n SHIFT\n");
 exit(1);
 }
 }
 else if(strcmp(argv[i], "-f") ==0){
 if(i + 1 <argc) {
 strcpy(fname ,argv[i+1]);
 }
 }
 } 
 if (fname != NULL){
 if((fp = fopen(fname, "r")) == NULL) {
 printf("ファイルを開けません\n" );
 exit(1); }
 }

 convert(direction, shift, fp);

 fclose(fp);

 return 0;
 } 

box
記事: 2002
登録日時: 14年前

Re: シーザー暗号について

#2

投稿記事 by box » 9年前

gyakusai さんが書きました: 修正をお願いいたします。
ということは、今は思ったとおりに動いていないということですね。
どんな入力に対してどんなパラメーターを与えたとき、どんな風になってほしいのに今はどんな結果を得てしまっているのか、説明をお願いします。
gyakusai さんが書きました: FILE *fp = stdin;ですでに実装されているのでしょうか?
たぶん。

後は、そのノッペリした字下げを何とかすることですね。今のコードは読みづらくて…。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 14年前

Re: シーザー暗号について

#3

投稿記事 by box » 9年前

gyakusai さんが書きました: コマンドライン引数として、ファイル名、-d(復号化)又は-e (暗号化)、-n x(xはシフト量)、-f fname(読み込むファイルの名前、ない場合は標準入力で暗号化、または複合化したい文章を入力) を与え
この部分、main関数で行なうよりもパラメーターを処理するための関数を用意する方がいいように思います。
また、-d, -e, -n, -f
の各パラメーターをこの順番で指定しなかった場合のことも考慮に入れる必要がありそうです。
後は、-dも-eもなかったら復号化も暗号化もできないのでエラーにするとか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: シーザー暗号について

#4

投稿記事 by みけCAT » 9年前

gyakusai さんが書きました:

コード:

 strcpy(fname ,argv[i+1]);
未定義動作であり、異常終了や任意のコードが実行可能な脆弱性の原因になるので、ヌルポインタが「指す」場所に書き込んではいけません。
strcpyの前に十分な領域を確保しましょう。

また、このままだとiが更新されずに無限ループになる可能性がありますね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る