C: Вывод с символами в шифре Цезаря шифрует, ПОЧЕМУ? pset2 cs50

Это проблема шифрования Цезаря в pset2 курса cs50x в edx.org.

Я уже решил эту проблему с помощью другого алгоритма, но это была моя первая попытка, и мне все еще интересно, почему все эти символы появляются в правой части текста Цезаря.

то есть. Я ввожу текст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");        
}

1 ответ

Решение

Основная проблема в том, что C не имеет полного, правильного или первоклассного типа "string". Строки в 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 что я добавил, это длина последовательности ненулевых символов в строке msg, Поэтому, когда вы создаете массив символов caesarMsg длины len, нет места для символа NUL для хранения.

for цикл выполняется правильно, но printf("%s", caesarMsg); будет продолжать печатать символы, пока не найдет NUL или не произойдет сбой.

Кстати, вы можете уменьшить два printf заявления в конце в один printf Скажите легко.

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

Строки и массивы символов являются частым источником путаницы для любого новичка в C, а некоторые не слишком новы для C. Некоторые дополнительные ссылки:

  • Я действительно рекомендую делать закладки на это comp.lang.c FAQ.
  • Я также убежден, что вы либо получите свою собственную копию, либо убедитесь, что у вас есть доступ к Kernighan и Ritchie's The C Programming Language, Second Edition (1988).

Рэнт: И кто бы ни создал string typedef является злом / совершает серьезную ошибку, вводя учеников в заблуждение, считая, что строки С являются "реальным" (или первоклассным) типом данных.


(*) NUL отличается от NULL, потому что NULL (нулевой указатель) приводится как указатель, так как он имеет тот же размер, что и другие указатели, где как NUL является нулевым символом (и либо размер char или же int).

Другие вопросы по тегам