Подтвердить что ты не робот

Как проверить, если заданная строка С++ или char * содержит только цифры?

Или, наоборот, найдите первый несимметричный символ.

Выполняют те же функции для строки и для char *?

4b9b3361

Ответ 1

Конечно, существует множество способов проверки строки только для числовых символов. Возможны два способа:

bool is_digits(const std::string &str)
{
    return str.find_first_not_of("0123456789") == std::string::npos;
}

или

bool is_digits(const std::string &str)
{
    return std::all_of(str.begin(), str.end(), ::isdigit); // C++11
}

Ответ 2

Несколько человек уже упомянули использовать isdigit(). Однако обратите внимание, что это не совсем тривиально, потому что char может быть подписано, что приведет к передаче отрицательного значения на isdigit(). Однако эта функция может принимать только положительные значения. То есть вы хотите что-то похожее на это:

if (s.end() == std::find_if(s.begin(), s.end(),
    [](unsigned char c)->bool { return !isdigit(c); })) {
    std::cout << "string '" << s << "' contains only digits\n";
}

Похоже, что рассуждение о преобразовании в unsigned char не очевидно. Итак, вот соответствующие цитаты из их соответствующих стандартов:

В соответствии с ИСО/МЭК 9899: 2011 (или ИСО/МЭК 9899: 1999) 7.4 параграфа 1 для аргументов функций из <ctype.h> применяется следующее:

... Во всех случаях аргумент равен int, значение которого должно быть представляемый как unsigned char или должен равняться значению макроса EOF. Если аргумент имеет любое другое значение, поведение undefined.

К сожалению, стандарт С++ не указывает, что char является неподписанным типом. Вместо этого он указывает в ИСО/МЭК 14882: 2011 3.9.1 [basic.fundamental] пункт 1:

... Определяется реализацией, может ли объект char содержать отрицательные значения....

Ясно, что отрицательное значение не может быть представлено как unsigned char. То есть, если char использует подписанный тип в реализации (на самом деле есть несколько, которые, например, подписаны на MacOS с использованием gcc или clang), существует опасность того, что вызов любой из функций <ctype.h> приведет к undefined.

Теперь, почему преобразование в unsigned char делает правильные вещи?

Согласно пункту 4.7 [conv.integral], пункт 2:

Если тип назначения не указан, результирующее значение представляет собой наименьшее беззнаковое целое, сравнимое с исходным целым числом (по модулю 2 n где n - количество бит, используемых для представления неподписанного типа). [Примечание. В представлении с двумя дополнениями это преобразование является концептуальным и нет изменений в битовой схеме (если нет усечения). -end note]

То есть преобразование из [потенциально] подписанного char в unsigned char хорошо определено и приводит к тому, что результат находится в допустимом диапазоне для функций <ctype.h>.

Ответ 3

isdigit(int) указывает, является ли символ цифрой. Если вы собираетесь использовать ASCII и базу 10, вы также можете использовать:

int first_non_digit_offset= strspn(string, "0123456789")

Ответ 4

В том же духе, что и Миша, но правильнее: sscanf(buf, "%*u%*c")==1.

scanf возвращает 0, если извлечение цифр %d завершается с ошибкой, и 2, если после цифр, отмеченных символом %c, есть что-либо. И поскольку * предотвращает сохранение значения, вы даже не можете получить переполнение.

Ответ 5

Заголовочный файл cctype имеет большое количество функций классификации символов, которые вы можете использовать для каждого символа в строке. Для числовых проверок это будет isdigit.

Следующая программа показывает, как проверять каждый символ строки C или С++ (процесс в значительной степени идентичен с точки зрения проверки фактических символов, единственная реальная разница в том, как получить длину):

#include <iostream>
#include <cstring>
#include <cctype>
int main (void) {
    const char *xyzzy = "42x";
    std::cout << xyzzy << '\n';
    for (int i = 0; i < std::strlen (xyzzy); i++) {
        if (! std::isdigit (xyzzy[i])) {
            std::cout << xyzzy[i] << " is not numeric.\n";
        }
    }

    std::string plugh ("3141y59");
    std::cout << plugh << '\n';
    for (int i = 0; i < plugh.length(); i++) {
        if (! std::isdigit (plugh[i])) {
            std::cout << plugh[i] << " is not numeric.\n";
        }
    }

    return 0;
}

Ответ 6

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

unsigned safe_atoi(const std::string& a)
{
    std::stringstream s(a);
    unsigned b;
    s >> b;
    return b;
}

Ответ 7

#include <regex>

std::string string( "I only have 3 dollars!" );
std::cout << std::regex_search( string, std::regex( "\\d+" ) ); // true

и

std::string string( "I only have three dollars!" );
std::cout << std::regex_search( string, std::regex( "\\d+" ) ); // false

Ответ 8

Из cplusplus.com вы можете использовать функцию isdigit следующим образом:

// isdigit example (C++)
#include <iostream>       // std::cout
#include <string>         // std::string
#include <locale>         // std::locale, std::isdigit
#include <sstream>        // std::stringstream

int main ()
{
  std::locale loc;
  std::string str="1776ad";
  if (isdigit(str[0],loc))
  {
    int year;
    std::stringstream(str) >> year;
    std::cout << "The year that followed " << year << " was " << (year+1) << ".\n";
  }
  return 0;
}

Примечание: существует 2 типа isdigit, другая версия является локальной независимой и основанной на ASCII.