Как преобразовать std::string в int в C++?
Использование std::stoi с обработкой ошибок
В современном C++ (C++11 и новее) лучший способ преобразовать std::string в int — это функция std::stoi. Она является частью заголовочного файла <string> и предоставляет встроенную обработку ошибок через исключения. В отличие от устаревшей atoi, которая просто возвращает 0 при ошибке (что не позволяет отличить "0" от ошибки), stoi генерирует исключения:
- std::invalid_argument — если строка не содержит чисел в начале.
- std::out_of_range — если число выходит за пределы диапазона int.
Кроме того, stoi принимает необязательный второй параметр — указатель на size_t, который сохраняет позицию первого символа, не участвующего в преобразовании. Это позволяет проверить, вся ли строка была преобразована.
Пример с полной обработкой ошибок
#include <iostream>
#include <string>
#include <stdexcept> // для исключений
int stringToInt(const std::string& str) {
try {
size_t pos = 0;
int result = std::stoi(str, &pos);
// Проверяем, что вся строка была преобразована
if (pos != str.length()) {
throw std::invalid_argument("Строка содержит лишние символы");
}
return result;
}
catch (const std::invalid_argument& e) {
std::cerr << "Ошибка: неверный формат строки: " << e.what() << std::endl;
return 0; // или другое значение по умолчанию
}
catch (const std::out_of_range& e) {
std::cerr << "Ошибка: число выходит за пределы диапазона int: " << e.what() << std::endl;
return 0;
}
}
int main() {
std::string s1 = "456";
std::string s2 = "123abc"; // содержит буквы
std::string s3 = "9999999999999"; // слишком большое число
int num1 = stringToInt(s1);
std::cout << "num1 + 10 = " << num1 + 10 << std::endl; // 466
int num2 = stringToInt(s2); // выведет ошибку
std::cout << "num2 = " << num2 << std::endl; // 0
int num3 = stringToInt(s3); // выведет ошибку
std::cout << "num3 = " << num3 << std::endl; // 0
return 0;
}
Как это работает
Функция stoi пропускает начальные пробелы, затем пытается преобразовать как можно больше символов в число. Параметр pos после вызова содержит индекс первого символа, который не был частью числа. Если pos < str.length(), значит, в строке есть "хвост" из нецифровых символов — это можно считать ошибкой (в зависимости от требований).
Альтернативы
- std::stringstream — более старый, но гибкий способ. Подходит для сложных сценариев (например, когда строка содержит несколько чисел).
- std::from_chars (C++17) — самый быстрый способ без исключений, но требует проверки кода ошибки.
Для большинства задач stoi с проверкой позиции — оптимальный выбор: он безопасный, читаемый и стандартный.
Использование std::stringstream для преобразования
Другой популярный подход — использовать std::stringstream из заголовочного файла <sstream>. Этот метод особенно удобен, когда нужно обработать строку с несколькими числами или смешанными данными.
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::string s = "456";
std::stringstream ss(s);
int num = 0;
if (ss >> num) {
// Проверяем, что после числа нет лишних символов
std::string remaining;
if (ss >> remaining) {
std::cerr << "Ошибка: строка содержит лишние символы" << std::endl;
return 1;
}
std::cout << "num + 10 = " << num + 10 << std::endl;
} else {
std::cerr << "Ошибка: не удалось преобразовать строку" << std::endl;
}
return 0;
}
Плюсы stringstream: он не использует исключения (подходит для систем, где они запрещены) и легко адаптируется для разных типов (double, float). Минусы: медленнее, чем stoi, и требует больше кода для проверки "хвостовых" символов. Для простого преобразования одного числа я рекомендую stoi, но для сложной обработки строк — stringstream.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги