Как проверить, является ли строка числом с помощью встроенной библиотеки?

Я пробовал использовать функцию 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;
    }
}

Вы можете перебирать каждый символ в строке, проверяя каждый с помощью isdigit.

001 13.08.2024 13:48

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

William Pursell 13.08.2024 15:33

Можно использовать регулярное выражение.

stark 13.08.2024 16:49

Не удивляйтесь, если вы не поймете ответов. Они используют указатели, о которых вы узнаете только на четвертой неделе CS50. Задание, о котором вы спрашиваете, относится ко второй неделе CS50.

Andreas Wenzel 13.08.2024 17:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не можете использовать 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.
chux - Reinstate Monica 13.08.2024 17:15

Есть много способов сделать это, с использованием библиотечных функций или без них.

Одним из наиболее гибких методов было бы использование 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.
chux - Reinstate Monica 13.08.2024 17:13

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