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
).