Форум программистов, компьютерный форум, киберфорум
Loafer
Войти
Регистрация
Восстановить пароль

Преобразование строки в число

Запись от Loafer размещена 02.10.2020 в 14:42
Показов 2122 Комментарии 5
Метки c++

Функция, проверяющая, что входная строка содержит корректное для заданного целочисленного типа значение в пределах допустимых значений. На вход передается строка, а необходимый целочисленный тип задается как параметр шаблона.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
bool check_is_integral(const std::string& str) {
  // Случай str == ''
  if (str.empty()) {
    return false;
  }
 
  // Случай str == '+' или str == '-'
  if (str.length() == 1 && (str[0] == '-' || str[0] == '+')) {
    return false;
  }
 
  // Случай str == '000' или str == '+000' или str == '-000'
  std::size_t begin = 0;
  if (str[begin] == '-' || str[begin] == '+') {
    begin++;
  }
  while (begin < str.length() && str[begin] == '0') {
    begin++;
  }
  if (begin >= str.length()) {
    return true;
  }
 
  // Основной алгоритм
  begin = 0;
  bool is_negative = false;
 
  if (std::is_signed<T>::value) {
    if (str[begin] == '-') {
      is_negative = true;
    }
    if (str[begin] == '-' || str[begin] == '+') {
      begin++;
    }
  } else if (str[begin] == '+') {
    begin++;
  }
 
  // Убираем ведущие нули
  while (str[begin] == '0') {
    begin++;
  }
 
  // Случай str == '1234a56'
  for (std::size_t i = begin; i < str.length(); ++i) {
    if (!std::isdigit(str[i])) {
      return false;
    }
  }
 
  // Проверка границ
  std::string ref_value =
      is_negative ? std::to_string(std::numeric_limits<T>::min()).substr(1)
                  : std::to_string(std::numeric_limits<T>::max());
 
  if ((str.length() - begin) < ref_value.length()) {
    return true;
  } else if ((str.length() - begin) > ref_value.length()) {
    return false;
  } else {
    for (std::size_t i = begin; i < str.length(); ++i) {
      if (ref_value[i - begin] > str[i]) {
        return true;
      } else if (ref_value[i - begin] < str[i]) {
        return false;
      }
    }
  }
 
  return true;
}
Метки c++
Размещено в C++
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 5
Комментарии
  1. Старый комментарий
    Аватар для Avazart
    Чем это лучше чем использовать std::strtoX...

    Например как я тут https://github.com/Avazart/Arg... ingUtils.h см ф-цию convert
    Запись от Avazart размещена 02.10.2020 в 15:54 Avazart вне форума
  2. Старый комментарий
    Аватар для Loafer
    Цитата Сообщение от Avazart
    Чем это лучше чем использовать std::strtoX...

    Например как я тут https://github.com/Avazart/Arg... ingUtils.h см ф-цию convert
    Функции из разряда std::strtoX, которые работают с беззнаковыми типами, не считают за ошибку, если им на вход приходит строка, представляющая собой отрицательное число.
    Плюс интрейфейс удобный. Если нужно проверить, что значение в строке str лежит в пределах типа int, то функцию надо использоваться следующим способом:
    C++
    1
    
    bool result = check_is_integral<int>(str);
    Запись от Loafer размещена 02.10.2020 в 16:02 Loafer вне форума
  3. Старый комментарий
    Аватар для Avazart
    Да если Вы видели я это в своем коде это учел.
    Запись от Avazart размещена 02.10.2020 в 18:55 Avazart вне форума
  4. Старый комментарий
    Аватар для Loafer
    Цитата Сообщение от Avazart
    Да если Вы видели я это в своем коде это учел.
    Вот в этом месте, наверное:
    C++
    1
    2
    
    if(is_unsigned_v<T> && s[0] == CharT('-'))
        throw out_of_range("out of range");
    Но под каждый целочисленный тип данных у Вас своя функция. А что делать, если надо преобразовать в std::size_t? В зависимости от архитектуры процессора (x86 или amd64) тип имеет разный размер.
    Запись от Loafer размещена 02.10.2020 в 19:41 Loafer вне форума
  5. Старый комментарий
    Аватар для Avazart
    Да наверное под size_t тоже стоило свою ф-цию завести.
    Но если Вы заметили все ф-ции вызывают шаблонную ф-цию convert так что с этим не должно быть проблем.

    Т.е. как то так:

    C++
    1
    2
    3
    4
    5
    
    template<typename CharT>
    auto strToSizeT(const std::basic_string<CharT>& s)
    {
      return detail::convert<unsigned long long,size_t>(s,std::strtoull,std::wcstoull);
    };
    P.S: Смотря на этот случай понял что стоит написать проверку по размерам типов, а не равенству типов.
    Запись от Avazart размещена 03.10.2020 в 11:00 Avazart вне форума
 
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru