Я изучаю курс CS50x. А домашнее задание набора задач 2 — это алгоритм Цезаря.
Я заставил его работать нормально. Но меня смущает одно:
функция bool only_digits - для нормальной работы требуется окончательный возврат true. Я искал в Google, и люди сказали, что должно быть возвращаемое значение по умолчанию, хорошо, я понимаю.
Но когда я переключил его с TRUE на FALSE, программа просто обработала все аргументы командной строки как FALSE. Поэтому программа не могла работать.
Я новичок в алгоритмах и программировании. Пожалуйста, помогите мне понять эту часть.
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
bool only_digits(string s);
char rotate(char c, int n);
int main(int argc, string argv[])
{
// Make sure program was run with just one command-line argument
// Also make sure every character in argv[1] is a digit
if (argc < 2 || argc >2 || only_digits(argv[1]) == false)
{
printf("Usage: ./caesar key\n");
return 1;
}
// Convert argument to int
int x = atoi(argv[1]);
// Prompt the user
string plaintext = get_string("plaintext: ");
// Encrypt the plaintext
printf("ciphertext: ");
for (int i = 0, len = strlen(plaintext); i < len; i++)
{
char cipher = rotate(plaintext[i], x);
printf("%c", cipher);
}
printf("\n");
}
// Function check if only digit
bool only_digits(string s)
{
for (int i = 0, len = strlen(s); i < len; i++)
{
if (isdigit(s[i]))
{
while(s[i] == '\0')
return true;
}
else
{
return false;
}
}
return true; /* This part, I dont understand why */
}
// Function rotate
char rotate(char c, int n)
{
if (isalpha(c))
{
if (isupper(c))
{
c = 'A' + (c - 'A' + n) % 26;
return c;
}
else c = 'a' + ((c - 'a' + n) % 26);
return c;
}
else return c;
}
string s
не является C. В C нет строкового типа.
Например. вы можете стереть половину этого тела цикла, просто сказав if (!isdigit(s[i]) return false;
. Возможно, тогда пост-петля return true;
будет иметь для вас больше смысла. Код while(s[i] == '\0') return true;
— ерунда. Цикл for
повторяется до конца, но не включает терминатор, поэтому while(s[i] == '\0')
будет никогда истинным, и, таким образом, бесполезный return true;
после этого никогда не будет выполнен.
Без return true;
в конце, что произойдет, если вы позвоните only_digits("")
?
@ Герхард Да, это так. Во всяком случае, в этом случае. Виноват заголовок Гарварда cs50.h
, который псевдоним char *
как string
(и нет, я не говорю, что это хорошая идея, совсем наоборот. Я давно говорил о том, каким ужасным «обучающим» инструментом является эта библиотека).
@WhozCraig, тогда напоминание о Минимальные, полные и проверяемые примеры должно быть в порядке.
@MOehm Я написал этот цикл while
, чтобы заставить его работать до конца строки, потому что я тестировал строку 111a
раньше, он проверял только первый символ. Но теперь, чтобы вспомнить это, я думаю, что я тоже где-то ошибся, поэтому мой код выглядел так.
@WhozCraig да, это имеет больше смысла, и, наконец, я это понимаю. Спасибо
Итак, я расскажу здесь об одной функции, той, что с return true
:
bool only_digits(string s)
{
for (int i = 0, len = strlen(s); i < len; i++)
{
if (isdigit(s[i]))
{
while(s[i] == '\0')
return true;
}
else
{
return false;
}
}
return true; /* This part, I dont understand why */
}
Итак, вы спрашиваете if (isdigit(s[i])
, а затем запускаете цикл while, который завершается, как только s[i] != '\0'
что уже верно, как только вы входите в if-тело.
Что вы хотели бы сделать, так это проверить, есть ли в вашей строке какие-либо нецифры. Что-то вроде
bool only_digits(string s)
{
for (int i = 0, len = strlen(s); i < len; i++)
{
if (!isdigit(s[i]))
return false;
}
return true; /* if we didn't find a non-digit, we're fine */
}
Спасибо. Я написал этот цикл while
, чтобы заставить его работать до конца строки, потому что я тестировал строку 111a
раньше, он проверял только первый символ. Сначала я не понял, как работает bool, но благодаря вашему коду понял.
Скорее вопрос: «Почему в этой функции бесполезный
while(s[i] == '\0') return true;
?:)
Если вы проверяете, состоит ли строка только из цифр, вы не можете быть уверены, пока не увидите все цифры, следовательно,return true
в конце. Но если вы видите не является цифрой, вы знаете, что символы не могут быть только цифрами, поэтому вы можете вернутьсяfalse
раньше, не увидев все символы.