2015-08-26 2 views
1

Я кодировал Vigenere Cipher как часть CS50. Это мой код.Vigenere Cipher Дополнительные символы

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

int main(int argc, string argv[]) 
{ 
    if(argc != 2) 
    { 
     printf("Bad Argument!\n"); 
     return 1; 
    } 

    for(int k = 0; k <= strlen(argv[1]) - 1; k++) 
    { 
     if (isalpha(argv[1][k]) == 0) 
     { 
      printf("Bad Argument!\n"); 
      return 1; 
     } 
    } 

    string s = GetString(); 
    char a[strlen(s)]; 

    int i, j = 0; 
    int l = strlen(argv[1]); 

    for (i = 0; i < strlen(s); i++) 
    { 
     int k = (int)(tolower(argv[1][j%l]) - 'a'); 

     if (s[i] >= 'A' && s[i] <= 'Z') 
     { 
      a[i] = (s[i] - 'A' + k) % 26 + 'A'; 
      j++; 
     } 
     else if (s[i] >= 'a' && s[i] <= 'z') 
     { 
      a[i] = s[i] - 'a' + k) % 26 + 'a'; 
      j++; 
     } 
     else 
      a[i] = s[i]; 
    } 

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

} 

Это мой код для pset2 vigenere.c. Однако, как только я скомпилирую его и запустил, я получаю разные символы в конце зашифрованного текста, например: TERMINAL SCREENSHOT

Итак, Check50 в некоторых случаях принимает ответ, а в других - нет.

:(encrypts "a" as "a" using "a" as keyword 
    \ expected output, but not "a\u001c������\n" 
:(encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword 
    \ expected output, but not "xoqmd, rby gflkp!v��\t��\n" 
:) encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword 
:) encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword 

Что я делаю неправильно?

ответ

1

Вы забыли добавить конечный нулевой байт в зашифрованную строку. Следовательно, все, что соответствует , строка в памяти (здесь, некоторые данные в стеке) печатается до тех пор, пока не встретится случайный нулевой байт.

Таким образом, выделить strlen(s) + 1 для дополнительного нулевого байта:

char a[strlen(s) + 1]; 

И установить последний элемент a к '\0':

a[strlen(s)] = '\0'; 

здесь означает: если x является в ячейке памяти 0x00, f ollowing расположение памяти 0x01.


Примечания:

  • Я предлагаю введение переменной как size_t plainstr_len = strlen(s); и использовать его в любом месте вместо простого strlen(s) ради спектакля в
2

Вы забыли NUL терминатор.

C не имеет встроенного типа, это «строка», и ваш инструктор CS50 оказывает вам плохую услугу, создавая typedef для «string» в «cs50.h». В C, «строка» - это массив символов с терминатором NUL в конце. Размер массива должен быть длиной строки плюс один.

Так первая ошибка в коде является

char a[strlen(s)]; 

, который должен быть

size_t length = strlen(s); 
char a[length+1]; 

Небольшая оптимизация кода будет заменить

for (i = 0; i < strlen(s); i++) 

с

for (i = 0; i < length; i++) 

Но самая большая проблема в вашем коде является отсутствие NUL терминатора, который вы можете исправить, поставив следующую строку после окончания цикла

a[length] = '\0'; 

Если вы серьезно относитесь к изучению C, I предложите перевести в другой университет. Понимание строк в C является ключом к написанию стабильного, надежного и безопасного кода. И потому, что ваш профессор скрывает детали от вас, вы ничего не учите.

+0

Я не думаю, что один профессор в одном классе является достаточной причиной для выхода из университета. – kamoroso94