-3
#include <stdio.h>
#include <cs50.h> //stdlib.h is included in cs50.h so I don't need it
#include <string.h>
#include <ctype.h>
#include <math.h>

int main(int argc, string argv[]) // command line input
{
    if(argc != 2) // check if there is only one input
    {
        printf("error\n");
        return 1;
    }

    int commandlength = strlen(argv[1]); // find string length of command string

    string key[commandlength + 1]; // taking the key from the input and putting it in something that will take less typing later

    for(int i = 0; i < commandlength; i++) // check if every char in the string is a letter
    {
        if(isalpha(argv[1][i]))
            continue;

        else
        {
            printf("error\n");
            return 1;
        }
    }

    strcpy(key[commandlength], argv[1]); // copy key from command line into a string called key
    string input = GetString();
    int inputlength = strlen(input); // length of string typed in when prompted
    int k = 0; // this will be used to iterate the key separately from i, since the key only iterates when applied to an alpha

    for(int i = 0; i < inputlength; i++)
    {
        if(ispunct(input[i]))
            printf("%c", input[i]);

        if(isspace(input[i]))
            printf("%c", input[i]);

        if(isupper(input[i]))
        {
            printf("%c", (input[i] + atoi(key[k]) % commandlength - 65) % 26 + 65);
            k++;
        }

        if(islower(input[i]))
        {
            printf("%c", (input[i] + atoi(key[k]) % commandlength - 97) % 26 + 97);
            k++;
        }        
    }

    printf("\n");
    return 0;
}

読む前に、私が学生であることを心に留めておいてください。「ほら、私はそれを修正しました」という単なるコード行よりも、詳細な説明を受け取る方がはるかに有益です. 私は提出物にこの投稿をリンクさせます。学問的誠実性と、模倣と助長について非常に厳しい規則があります。それを念頭に置いていただければ幸いです。

このプロジェクトの目的は、vigenere 暗号を作成することです。以下は、私の先生が提供した指示です。

今週の最後の課題は、vigenere.c で、Vigenere の暗号を使用してメッセージを暗号化するプログラムを作成することです。このプログラムは、1 つのコマンド ライン引数を受け入れる必要があります。つまり、完全にアルファベット文字で構成されるキーワード k です。プログラムがコマンド ライン引数なしで実行された場合、複数のコマンド ライン引数が指定された場合、またはアルファベット以外の文字を含む 1 つのコマンド ライン引数が指定された場合、プログラムは文句を言ってすぐに終了し、main は 1 を返します (したがって、独自のテストで検出できるエラーを示します)。それ以外の場合、プログラムはユーザーに平文の文字列 p の入力を求めるプロンプトを表示し、k を使用して Vigenère の暗号に従って暗号化し、最終的に結果を出力して終了し、main は 0 を返す必要があります。

k の文字については、A と a を 0、B と b を 1、…、Z と z を 25 として扱わなければなりません。手紙。他のすべての文字 (数字、記号、スペース、句読点など) は、変更せずに出力する必要があります。さらに、コードが k の j 番目の文字を p の i 番目の文字に適用しようとしているが、後者がアルファベット以外の文字であることが判明した場合、k の j 番目の文字を p の次のアルファベット文字に適用するのを待つ必要があります。 ; k の次の文字に進んではいけません。最後に、プログラムは p の各文字の大文字と小文字を保持する必要があります。

コードを反復処理し、暗号化されているフレーズよりも短い場合はキーがループすることを確認し、キーを非アルファ文字に適用していないことを確認するという要件を満たしていると確信しています。ただし、暗号化する文字列を入力するように求められる前にセグメンテーションのデフォルトが表示されるため、問題はコードの上半分にあると確信しています。コードをかなり調べましたが、なぜセグメンテーション違反が続くのかまだわかりません。

4

4 に答える 4

1

このステートメントを変更

strcpy(key[commandlength], argv[1]); 

strcpy( key, argv[1] ); 

key[commandlength] は char 型のオブジェクトであり、この無効な構造を使用すると文字列のアドレスとして値が使用されます

strcpy(key[commandlength], argv[1]); 

またcontinue、ループで使用することはお勧めできません。それ以外の

for(int i = 0; i < commandlength; i++) // check if every char in the string is a letter
{
    if(isalpha(argv[1][i]))
        continue;

    else
    {
        printf("error\n");
        return 1;
    }
}

私は簡単に書くだろう

for(int i = 0; i < commandlength; i++) // check if every char in the string is a letter
{
    if( !isalpha(argv[1][i] ) )
    {
        printf("error\n");
        return 1;
    }
}

そして、 BLUEPIXYが代わりに指摘したように

string key[commandlength + 1]; 

あるだろう

char key[commandlength + 1]; 

次のようなタイプ定義がない場合

typedef char string;

ただし、実際にそのような typedef がある場合は、次のステートメント

string input = GetString();

入力用に関数 strlen を呼び出そうとしているため、無効になります。

int inputlength = strlen(input); 

また、このステートメントの例のように、コードでマジック ナンバーを使用しないでください。

printf("%c", (input[i] + atoi(key[k]) % commandlength - 65) % 26 + 65);

65が「A」だと思います。したがって、65 の代わりに明示的に文字リテラル 'A' を使用する方がよいでしょう。

于 2014-09-26T10:10:14.680 に答える
0

よくわからない場合は、次のようにソースをコンパイルしてください: "gcc -Wall -g source.c" ; プログラムを実行します。プログラムがクラッシュした後、「dgb ./prog core」を実行します

gdb タイプ「bt」に入力すると、seg fault が発生する文字列の数が表示されます

作業ディレクトリにコア ダンプを作成できない場合は、次のコマンドを実行します: "ulimit -c unlimited" (bash 環境の場合)

于 2014-09-26T13:56:28.973 に答える