-3

これは edx.org の cs50x コースの pset2 にある Caesar の暗号暗号化問題です。

私はすでに別のアルゴリズムでこの問題を解決しましたが、これは私の最初の試みであり、シーザーテキストの右側にこれらすべての記号が表示される理由にまだ興味があります.

すなわち。テキスト「Testing」を入力すると、出力は「Fqefuz�����w����l��B��」になりますが、答えは記号なしで正解です。

誰か私にそれを説明できますか?

int main(int argc, string argv[])
{
    bool keyOk = false;
    int k = 0;   
    do
    {
        if(argc != 2) // Checking if the key was correctly entered.
        {
            printf("You should enter the key in one argument from"
                " the prompt(i.e. './caesar <key>').\n");
            return 1;
        }
        else
        {
            k = atoi(argv[1]); // Converting string to int.
            keyOk = true; // Approving key.
        }
    }
    while(keyOk == false);

    string msg = GetString(); // Reading user input.
    char caesarMsg[strlen(msg)];

    for(int i=0, n = strlen(msg); i < n; i++)
    {

        if( (msg[i] >= 'a') && (msg[i] <= 'z') )
        // Processing lower case characters
        {
            caesarMsg[i] = ((((msg[i] - 97) + k) % 26) + 97);
        }
        else if( (msg[i] >= 'A') && (msg[i] <= 'Z') )
        // Processing upper case characters
        {
            caesarMsg[i] = ((((msg[i] - 65) + k) % 26) + 65);
        }
        else
        {
            caesarMsg[i] = msg[i];
        }

    }
    printf("%s", caesarMsg);
    printf("\n");        
}
4

1 に答える 1

2

根本的な問題は、C には完全な、適切な、またはファーストクラスの「文字列」データ型がないことです。Cでは、文字列は実際にはNUL( '\0') (*) 文字で終了する文字配列です。

見る

  string msg = GetString();  // Reading user input.
  char caesarMsg[strlen(msg)];

これは、

  char* msg = GetString();  /* User or library function defined elsewhere */

/* calculates the length of the string s, excluding  the terminating null
   byte ('\0') */
  size_t len = strlen(msg);  

  char caesarMsg[len];  /* Create an character (byte) array of size `len` */

これにより、このセクションが正しく機能しない理由が明確になることを願っています。追加した変数lenは、文字列内の非 NUL 文字のシーケンスの長さですmsg。したがって、caesarMsglengthの文字配列を作成するlenと、NUL 文字を格納する余地がありません。

forループは正しく実行されprintf("%s", caesarMsg);ますが、NUL が検出されるかクラッシュするまで文字を出力し続けます。

ところでprintf、最後の 2 つのステートメントをprintf簡単に 1 つのステートメントに減らすことができます。

printf("%s\n", caesarMsg); 

文字列と文字配列は、C を初めて使用する人や、それほど C に慣れていない人にとって、頻繁に混乱の原因となります。いくつかの追加の参照:


暴言: そして、stringtypedef を作成した人は誰でも、C の文字列が「実際の」(またはファーストクラスの) データ型であると学生を誤解させることによって、悪/重大な誤りを犯しています。


(*) NULはNULLとは異なります。なぜなら、NULL(null ポインター) はポインターとしてキャストされるため、他のポインターと同じサイズになります。asNULは null 文字 (および acharまたはのいずれかのサイズint) です。

于 2014-07-17T21:28:58.967 に答える