Я пробовал использовать функцию isdigit
, но она работает только для символов. Я знаю, что могу написать функцию, которая будет проверять каждый char
в строке, но есть ли уже встроенный способ в c?
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Usage: ./caesar key");
return 1;
}
else if (isdigit(argv[1]) != 1)
{
printf("Usage: ./caesar key");
return 1;
}
}
Если ваша программа возвращает ненулевое значение из основного, она должна была вывести сообщение об ошибке. Если вы собираетесь вывести оператор использования на стандартный вывод, программа должна вернуть 0. Если вы собираетесь возвращать ненулевое значение, программа должна вывести сообщение об ошибке на стандартный вывод. Хотя, к сожалению, это распространенная практика, вывод инструкции об использовании на стандартный вывод и возврат ненулевого значения не является лучшей практикой.
Можно использовать регулярное выражение.
Не удивляйтесь, если вы не поймете ответов. Они используют указатели, о которых вы узнаете только на четвертой неделе CS50. Задание, о котором вы спрашиваете, относится ко второй неделе CS50.
Вы не можете использовать isdigit()
так, как вы это делаете в вопросе: его аргумент должен быть одним символом (все значения типа unsigned char
) или специальным отрицательным значением EOF
. Передача строки имеет неопределенное поведение.
На ваш вопрос есть много возможных ответов, в зависимости от того, что вы подразумеваете под строкой, являющейся числом:
Чтобы проверить, состоит ли строка, на которую указывает указатель s
, только из цифр с использованием strspn
, определенного в <string.h>
:
if (*s && s[strspn(s, "0123456789")] == '\0') {
// s is not empty and only contains digits
}
чтобы проверить, представляет ли оно десятичное целое число с необязательными пробелами аренды и необязательным знаком:
char *p;
strtol(s, &p, 10);
if (p != s && *p == '\0') {
// s contains the decimal representation of an integer
}
Вот альтернатива правильному использованию isdigit
:
#include <cs50.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
bool string_is_number(const char *s) {
// reject empty string
if (*s == '\0') {
return false;
}
// skip digits
while (isdigit((unsigned char)*s)) {
s++;
}
// return true if all characters are digits
return *s == '\0';
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: ./caesar key\n");
return 1;
}
if (!string_is_number(argv[1])) {
printf("Usage: ./caesar key\n");
printf(" key must be a number\n");
return 1;
}
int key = strtol(argv[1], NULL, 10);
//...
}
strtol(s, &p, 10)
побочный эффект: может установить errno
.
Есть много способов сделать это, с использованием библиотечных функций или без них.
Одним из наиболее гибких методов было бы использование strtol
(семейство), поскольку он также выполняет преобразование строки в целое число. Пример:
#include <stdlib.h>
bool isnumber (const char* str, int* result)
{
char* endptr = NULL;
*result = strtol(str, &endptr, 10);
return endptr != str;
}
// usage example:
int n;
if (isnumber("12345", &n))
{
printf("%d is a number.\n", n);
}
isnumber("12345xyz", &n)
также возвращает true.
Вы можете перебирать каждый символ в строке, проверяя каждый с помощью
isdigit
.