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

Для преобразования строки в число используются следующие функции:

  • atoi() — преобразует C-строку в число, имеющее тип int. Прототип функции:
#include <cstdlib> /* или #include <stdlib.h> */
int atoi(const char *str);

Считывание символов производится пока они соответствуют цифрам. Иными словами, в строке могут содержаться не только цифры. Пробельные символы в начале строки игнорируются. Пример преобразования:

std::cout << std::atoi("25") << std::endl;        // 25
std::cout << std::atoi("2.5") << std::endl;       // 2
std::cout << std::atoi("5str") << std::endl;      // 5
std::cout << std::atoi("5s10") << std::endl;      // 5
std::cout << std::atoi(" \t\n 25") << std::endl;  // 25
std::cout << std::atoi("-25") << std::endl;       // -25
std::cout << std::atoi("str") << std::endl;       // 0

Если значение выходит за диапазон значений типа int, то в VC++ возвращается максимальное или минимальное значение типа int и переменной errno присваивается значение ERANGE:

std::cout << std::atoi("2147483649") << std::endl; // 2147483647
std::cout << errno << std::endl;                   // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}

В MinGW будет усечение значения:

std::cout << std::atoi("2147483649") << std::endl; // -2147483647
std::cout << errno << std::endl;                   // 0
  • atol() — преобразует C-строку в число, имеющее тип long. Прототип функции:
#include <cstdlib> /* или #include <stdlib.h> */
long atol(const char *str);

Пример преобразования:

std::cout << std::atol("25") << std::endl;        // 25
std::cout << std::atol(" \n -25") << std::endl;   // -25
std::cout << std::atol("2.5") << std::endl;       // 2
std::cout << std::atol("5str") << std::endl;      // 5
std::cout << std::atol("5s10") << std::endl;      // 5
std::cout << std::atol("str") << std::endl;       // 0

Если значение выходит за диапазон значений типа long, то в VC++ возвращается максимальное или минимальное значение типа long и переменной errno присваивается значение ERANGE:

std::cout << std::atol("2147483649") << std::endl; // 2147483647
std::cout << errno << std::endl;                   // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}

В MinGW будет усечение значения:

std::cout << std::atol("2147483649") << std::endl; // -2147483647
std::cout << errno << std::endl;                   // 0
  • atoll() — преобразует C-строку в число, имеющее тип long long. Прототип функции:
#include <cstdlib> /* или #include <stdlib.h> */
long long atoll(const char *str);

Пример преобразования:

std::cout << std::atoll("9223372036854775807") << std::endl;
// 9223372036854775807

Если значение выходит за диапазон значений типа long long, то возвращается максимальное или минимальное значение типа long long и переменной errno присваивается значение ERANGE:

std::cout << std::atoll("9223372036854775809") << std::endl;
// 9223372036854775807
std::cout << errno << std::endl; // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}
  • _atoi64() — преобразует C-строку в число, имеющее тип __int64. Прототип функции:
#include <cstdlib> /* или #include <stdlib.h> */
__int64 _atoi64(const char *str);

Пример преобразования:

std::cout << _atoi64("9223372036854775807") << std::endl;
// 9223372036854775807

Если значение выходит за диапазон значений типа __int64, то возвращается максимальное или минимальное значение типа __int64 и переменной errno присваивается значение ERANGE:

std::cout << _atoi64("9223372036854775809") << std::endl;
// 9223372036854775807
std::cout << errno << std::endl; // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}
  • strtol() и strtoul() — преобразуют C-строку в число, имеющее тип long и unsigned long соответственно. Прототипы функций:
#include <cstdlib> /* или #include <stdlib.h> */
long strtol(const char *str, char **endPtr, int radix);
unsigned long strtoul(const char *str, char **endPtr, int radix);

Пробельные символы в начале строки игнорируются. Считывание символов заканчивается на символе не являющемся записью числа. Указатель на этот символ доступен через параметр endPtr, если он не равен NULL. В параметре radix можно указать систему счисления (число от 2 до 36). Если в параметре radix задано число 0, то система счисления определяется автоматически. Пример преобразования:

char *p = nullptr;
std::cout << std::strtol("25", NULL, 0) << std::endl;    // 25
std::cout << std::strtol("025", NULL, 0) << std::endl;   // 21
std::cout << std::strtol("0x25", NULL, 0) << std::endl;  // 37
std::cout << std::strtol("111", NULL, 2) << std::endl;   // 7
std::cout << std::strtol("025", NULL, 8) << std::endl;   // 21
std::cout << std::strtol("0x25", NULL, 16) << std::endl; // 37
std::cout << std::strtol("5s10", &p, 0) << std::endl;    // 5
std::cout << p << std::endl;                             // s10

Если в строке нет числа, то возвращается число 0. Если число выходит за диапазон значений для типа, то значение будет соответствовать минимальному (LONG_MIN или 0) или максимальному (LONG_MAX или ULONG_MAX) значению для типа, а переменной errno присваивается значение ERANGE. Пример:

std::cout << std::strtol("str", NULL, 0) << std::endl;   // 0
std::cout << std::strtol("2147483649", NULL, 0) 
          << std::endl; // 2147483647 (соответствует LONG_MAX)
std::cout << errno << std::endl; // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}
errno = 0; // Сбрасываем флаг ошибки
std::cout << std::strtol("25", NULL, 0) << std::endl; // 25
if (errno != ERANGE) {
   std::cout << "OK" << std::endl; // OK
}
  • strtoll() и strtoull() — преобразуют C-строку в число, имеющее тип long long и unsigned long long соответственно. Прототипы функций:
#include <cstdlib> /* или #include <stdlib.h> */
long long strtoll(const char *str, char **endPtr, int radix);
unsigned long long strtoull(const char *str, char **endPtr,
                            int radix);

Пробельные символы в начале строки игнорируются. Считывание символов заканчивается на символе не являющемся записью числа. Указатель на этот символ доступен через параметр endPtr, если он не равен NULL. В параметре radix можно указать систему счисления (число от 2 до 36). Если в параметре radix задано число 0, то система счисления определяется автоматически. Пример преобразования:

char *p = nullptr;
std::cout << std::strtoll("25", NULL, 0) << std::endl;    // 25
std::cout << std::strtoll("025", NULL, 0) << std::endl;   // 21
std::cout << std::strtoll("0x25", NULL, 0) << std::endl;  // 37
std::cout << std::strtoll("111", NULL, 2) << std::endl;   // 7
std::cout << std::strtoll("025", NULL, 8) << std::endl;   // 21
std::cout << std::strtoll("0x25", NULL, 16) << std::endl; // 37
std::cout << std::strtoll("5s10", &p, 0) << std::endl;    // 5
std::cout << p << std::endl;                              // s10

Если в строке нет числа, то возвращается число 0. Если число выходит за диапазон значений для типа, то значение будет соответствовать минимальному (LLONG_MIN или 0) или максимальному (LLONG_MAX или ULLONG_MAX) значению для типа, а переменной errno присваивается значение ERANGE. Пример:

std::cout << std::strtoll("str", NULL, 0) << std::endl;   // 0
std::cout << std::strtoll("9223372036854775809", NULL, 0)
   << std::endl; // 9223372036854775807 (соответствует LLONG_MAX)
std::cout << errno << std::endl; // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}
  • _strtoi64() и _strtoui64() — преобразуют C-строку в число, имеющее тип __int64 и unsigned __int64 соответственно. Прототипы функций:
#include <cstdlib> /* или #include <stdlib.h> */
__int64 _strtoi64(const char *str, char **endPtr, int radix);
unsigned __int64 _strtoui64(const char *str, char **endPtr,
                            int radix);

Пробельные символы в начале строки игнорируются. Считывание символов заканчивается на символе не являющемся записью числа. Указатель на этот символ доступен через параметр endPtr, если он не равен NULL. В параметре radix можно указать систему счисления (число от 2 до 36). Если в параметре radix задано число 0, то система счисления определяется автоматически. Пример преобразования:

char *p = nullptr;
std::cout << _strtoi64("25", NULL, 0) << std::endl;    // 25
std::cout << _strtoui64("25", NULL, 0) << std::endl;   // 25
std::cout << _strtoi64("025", NULL, 0) << std::endl;   // 21
std::cout << _strtoi64("0x25", NULL, 0) << std::endl;  // 37
std::cout << _strtoi64("111", NULL, 2) << std::endl;   // 7
std::cout << _strtoi64("025", NULL, 8) << std::endl;   // 21
std::cout << _strtoi64("0x25", NULL, 16) << std::endl; // 37
std::cout << _strtoi64("5s10", &p, 0) << std::endl;    // 5
std::cout << p << std::endl;                           // s10

Если в строке нет числа, то возвращается число 0. Если число выходит за диапазон значений для типа, то значение будет соответствовать минимальному или максимальному значению для типа, а переменной errno присваивается значение ERANGE. Пример:

std::cout << _strtoi64("str", NULL, 0) << std::endl;   // 0
std::cout << _strtoi64("9223372036854775809", NULL, 0)
          << std::endl; // 9223372036854775807
std::cout << errno << std::endl; // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}
  • strtoimax() и strtoumax() — преобразуют C-строку в число, имеющее тип intmax_t и uintmax_t соответственно. Прототипы функций:
#include <inttypes.h>
intmax_t strtoimax(const char *str, char **endPtr, int radix);
typedef long long intmax_t;
uintmax_t strtoumax(const char *str, char **endPtr, int radix);
typedef unsigned long long uintmax_t;

Пробельные символы в начале строки игнорируются. Считывание символов заканчивается на символе не являющемся записью числа. Указатель на этот символ доступен через параметр endPtr, если он не равен NULL. В параметре radix можно указать систему счисления (число от 2 до 36). Если в параметре radix задано число 0, то система счисления определяется автоматически. Пример преобразования:

char *p = nullptr;
std::cout << strtoumax("25", NULL, 0) << std::endl;    // 25
std::cout << strtoimax("25", NULL, 0) << std::endl;    // 25
std::cout << strtoimax("025", NULL, 0) << std::endl;   // 21
std::cout << strtoimax("0x25", NULL, 0) << std::endl;  // 37
std::cout << strtoimax("111", NULL, 2) << std::endl;   // 7
std::cout << strtoimax("025", NULL, 8) << std::endl;   // 21
std::cout << strtoimax("0x25", NULL, 16) << std::endl; // 37
std::cout << strtoimax("5s10", &p, 0) << std::endl;    // 5
std::cout << p << std::endl;                           // s10

Если в строке нет числа, то возвращается число 0. Если число выходит за диапазон значений для типа, то значение будет соответствовать минимальному (INTMAX_MIN или 0) или максимальному (INTMAX_MAX или UINTMAX_MAX) значению для типа, а переменной errno присваивается значение ERANGE. Пример:

// #include <stdint.h>
std::cout << INTMAX_MIN << std::endl;    // -9223372036854775808
std::cout << INTMAX_MAX << std::endl;    // 9223372036854775807
std::cout << UINTMAX_MAX << std::endl;   // 18446744073709551615
std::cout << strtoimax("str", NULL, 0) << std::endl;  // 0
std::cout << strtoimax("9223372036854775809", NULL, 0)
          << std::endl; // 9223372036854775807
std::cout << errno << std::endl; // 34
// #include <math.h> или #include <errno.h>
if (errno == ERANGE) {
   std::cout << "Выход за диапазон значений" << std::endl;
}
  • atof() — преобразует C-строку в число, имеющее тип double. Функция _atof_l() позволяет дополнительно задать локаль (от локали зависит десятичный разделитель вещественных чисел). Прототипы функций:
#include <cstdlib> /* или #include <stdlib.h> */
double atof(const char *str);
double _atof_l(const char *str, _locale_t locale);

Пример преобразования:

std::cout << std::atof("25") << std::endl;        // 25
std::cout << std::atof("2.5") << std::endl;       // 2.5
std::cout << std::atof("5.1str") << std::endl;    // 5.1
std::cout << std::atof("5s10") << std::endl;      // 5
std::cout << std::atof("str") << std::endl;       // 0
// #include <clocale>
_locale_t locale = _create_locale(LC_NUMERIC, "dutch");
std::cout << std::atof("2,5") << std::endl;       // 2
std::cout << _atof_l("2,5", locale) << std::endl; // 2.5
_free_locale(locale);
  • strtod() — преобразует C-строку в вещественное число, имеющее тип double. Функция _strtod_l() позволяет дополнительно задать локаль. Прототипы функций:
#include <cstdlib> /* или #include <stdlib.h> */
double strtod(const char *str, char **endPtr);
double _strtod_l(const char *str,char **endPtr,
                 _locale_t locale);

Пробельные символы в начале строки игнорируются. Считывание символов заканчивается на символе не являющемся записью вещественного числа. Указатель на этот символ доступен через параметр endPtr, если он не равен NULL. Пример преобразования:

char *p = nullptr;
std::cout << std::strtod(" \t\n 25", NULL) << std::endl; // 25
std::cout << std::strtod("2.5", NULL) << std::endl;      // 2.5
std::cout << std::strtod("5.1str", NULL) << std::endl;   // 5.1
std::cout << std::strtod("14.5e5s10", &p)
          << std::endl;                         // 1.45e+06
std::cout << p << std::endl;                    // s10

Обратите внимание: от настроек локали зависит десятичный разделитель вещественных чисел:

// #include <clocale>
_locale_t locale = _create_locale(LC_NUMERIC, "dutch");
std::cout << std::strtod("2,5", NULL) << std::endl;       // 2
std::cout << _strtod_l("2,5", NULL, locale) << std::endl; // 2.5
_free_locale(locale);

Если в строке нет числа, то возвращается число 0. Если число выходит за диапазон значений для типа, то возвращается значение -HUGE_VAL или HUGE_VAL, а переменной errno присваивается значение ERANGE;

  • strtof() — преобразует C-строку в вещественное число, имеющее тип float. Прототип функции:
#include <cstdlib> /* или #include <stdlib.h> */
float strtof(const char *str, char **endPtr);

Пробельные символы в начале строки игнорируются. Считывание символов заканчивается на символе не являющемся записью вещественного числа. Указатель на этот символ доступен через параметр endPtr, если он не равен NULL. Пример преобразования (обратите внимание: от настроек локали зависит десятичный разделитель вещественных чисел):

std::setlocale(LC_ALL, "C");
char *p = nullptr;
std::cout << std::strtof(" \t\n 25", NULL) << std::endl; // 25
std::cout << std::strtof("2.5", NULL) << std::endl;      // 2.5
std::cout << std::strtof("5.1str", NULL) << std::endl;   // 5.1
std::cout << std::strtof("14.5e5s10", &p)
          << std::endl;                             // 1.45e+06
std::cout << p << std::endl;                        // s10
std::setlocale(LC_ALL, "Russian_Russia.1251");
std::cout << std::strtof("2.5", NULL) << std::endl; // 2
std::cout << std::strtof("2,5", NULL) << std::endl; // 2.5

Если в строке нет числа, то возвращается число 0. Если число выходит за диапазон значений для типа, то возвращается значение –HUGE_VALF или HUGE_VALF, а переменной errno присваивается значение ERANGE;

  • strtold() — преобразует C-строку в вещественное число, имеющее тип long double. Прототип функции:
#include <cstdlib> /* или #include <stdlib.h> */
long double strtold(const char *str, char **endPtr);

Пробельные символы в начале строки игнорируются. Считывание символов заканчивается на символе не являющемся записью вещественного числа. Указатель на этот символ доступен через параметр endPtr, если он не равен NULL. Пример преобразования:

char *p = nullptr;
std::cout << std::strtold(" \t\n 25", NULL) << std::endl; // 25
std::cout << std::strtold("2.5", NULL) << std::endl;      // 2.5
std::cout << std::strtold("5.1str", NULL) << std::endl;   // 5.1
std::cout << std::strtold("14.5e5s10", &p)
          << std::endl;                             // 1.45e+06
std::cout << p << std::endl;                        // s10

Если в строке нет числа, то возвращается число 0. Если число выходит за диапазон значений для типа, то возвращается значение –HUGE_VALL или HUGE_VALL, а переменной errno присваивается значение ERANGE.

Все рассмотренные в этом разделе функции позволяют преобразовать всю C-строку в число. Если необходимо преобразовать отдельный символ (представляющий число) в соответствующее целое число от 0 до 9, то можно воспользоваться следующим кодом:

char ch = '8';
int n = ch - '0';            // Эквивалентно int n = 56 - 48;
std::cout << n << std::endl; // 8

В переменной типа char хранится код символа, а не сам символ. Символы от '0' до '9' в кодировке ASCII имеют коды от 48 до 57 соответственно. Следовательно, чтобы получить целое число от 0 до 9 достаточно вычесть из текущего символа код символа '0'. В качестве еще одного примера сохраним все цифры, встречающиеся в C-строке, в целочисленном массиве (листинг 5.2).

Листинг 5.2. Преобразование символов C-строки в отдельные цифры

#include <iostream>

int main() {
   char str[] = "abc0123456789";
   const int ARR_SIZE = 10;
   int arr[ARR_SIZE] = {0}, index = 0;
   for (char *p = str; *p; ++p) {       // Перебираем строку
      if (*p >= '0' && *p <= '9') {
         arr[index] = *p - '0';
         ++index;
         if (index >= ARR_SIZE) break;
      }
   }
   for (int i = 0; i < ARR_SIZE; ++i) { // Выводим значения
      std::cout << arr[i] << std::endl;
   }
   return 0;
}

Для преобразования строки в число можно также воспользоваться функциями sscanf() и _snscanf(). Прототипы функций:

#include <cstdio> /* или #include <stdio.h> */
int sscanf(const char *str, const char *format, ...);
int _snscanf(const char *str, size_t maxCount, const char *format, ...);

В параметре str указывается C-строка, содержащая число, в параметре maxCount — максимальное количество просматриваемых символов в строке, а в параметре format — строка специального формата, внутри которой задаются спецификаторы, аналогичные применяемым в функции printf() (см. разд. 2.9), а также некоторые дополнительные спецификаторы. В последующих параметрах передаются адреса переменных. Функции возвращают количество произведенных присваиваний. Пример получения двух целых чисел:

// #include <clocale>
std::setlocale(LC_ALL, "Russian_Russia.1251");
char str[] = "20 30 str";
int n = 0, k = 0;
int count = std::sscanf(str, "%d%d", &n, &k);
// #include <cstring>
// int count = _snscanf(str, std::strlen(str), "%d%d", &n, &k);
if (count == 2) {
   std::cout << "n = " << n << std::endl; // n = 20
   std::cout << "k = " << k << std::endl; // k = 30
}
else std::cout << "Не удалось преобразовать" << std::endl;

Функция sscanf() не производит никакой проверки длины строки, что может привести к ошибке. Обязательно указывайте ширину при использовании спецификатора %s (например, %255s). Кроме того, следует учитывать, что функция не проверяет возможность выхода значения за диапазон значений для типа, что может привести к неправильному результату. Функция никак об этом вас не предупредит, поэтому лучше использовать функции, рассмотренные в начале этого раздела.

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов