Problem Set2 Hail, Caesar!/Parlez-vous français?

Parlez-vous français?で苦しめられる。

①どう頑張っても当初、おかしな結果が出力された下記のコード
gist.github.com

原因は...

  • C言語の仕様でmainの引数は書き換えてはいけない(ことになっている)
  • mainの引数 = mainに代入される値のこと。ここで言えば、argc, argv[]の2つ

string keyword = argv[1]としているから、keywordは実質mainの引数なので、(keywordを)書き換えてはいけない

コンパイラーは上記をチェックしてはくれないため、
実行まではされるが結果がめちゃくちゃになって初めてわかるのである...

②いざ、char k = keyword[j] - 97などと定義をしてみた。
するとunused variable key & 下で使ってるのにundeclared variable の警告。

原因は...
ifの中で定義された変数 char k は、ifの中でしか使えない = 外では使えない
すなわち...{}の内側で定義をしても、その{}内でしか通用しないルール である。

ひとたび{}の外側で定義したあと、{}の内側で代入する分には、
{}を抜けても代入した値は保持されたまま、次にすすめる。

というわけで最終的なコードは

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

int main (int argc, string argv[]) {
    
    // check if you type a single command-line argument
    if (argc != 2) {
        printf ("Type ./vigenere keyword");
        return 1;
    }
    
    else {
        string keyword = argv[1];
        // check if the keyword is composed entirely of alphabetical characters
        int count = 0;
        for (int h = 0; h < strlen(keyword); h++) {
            if (isalpha(keyword[h]) == 0) count++;
        }
        if (count > 0) {
            printf ("Type alphabetical characters.");
            return 1;
        }
        else {
            // now get the plaintext
            string s = GetString();
            
            int j = 0;        
            for (int i = 0; i< strlen(s); i++) {
                
                j = j % strlen(keyword);
                
                // convert keyword[j] to 0-25
                char k;
                if (65 <= keyword[j] && keyword[j] <= 90) {
                    k = keyword[j] - 65;
                }
                else if (97 <= keyword[j] && keyword[j] <= 122) {
                    k = keyword[j] - 97;
                }
                
                // now encrypt the plaintext!
                if (65 <= s[i] && s[i] <= 90) {
                    // convert ASCII code to 0-25 (LARGE LETTERS)
                    char letter = s[i] - 65;
                    letter = (letter + k) % 26;
                    // reconvert
                    letter = letter + 65;
                    printf ("%c", letter);
                    j++;
                }
                else if (97 <= s[i] && s[i] <= 122) {
                    // convert ASCII code to 0-25 (small letters)
                    char letter = s[i] - 97;
                    letter = (letter + k) % 26;
                    // reconvert
                    letter = letter + 97;
                    printf("%c", letter);
                    j++;
                }      
                else {
                    printf ("%c", s[i]);
                }
            }
        printf ("\n");
        return 0;  
        }
    }
}