JavaRush /Курсы /C++ SELF /Преобразование строки в число

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

C++ SELF
2 уровень , 5 лекция
Открыта

1. std::stoi: базовая идея

Иногда кажется, что ввод числа — это всегда std::cin >> x; и готово. Но как только вы захотите прочитать строку целиком (например, «Имя Фамилия», адрес, комментарий, фразу с пробелами), вы почти автоматически переходите на std::getline. А дальше возникает бытовая задача: «Окей, я прочитал строку, но там же число, как мне сделать из неё int?».

Представьте консольную анкету: имя — строка, год рождения — вроде бы число, но вы хотите читать всё через getline, чтобы ввод был единообразным и без сюрпризов. Или пользователь вводит сумму 1500, но вы хотите сначала прочитать её как текст (строка), а потом уже интерпретировать как число. Вот тут и появляется std::stoi.

std::stoi — это функция стандартной библиотеки C++, которая пытается интерпретировать строку как целое число типа int. Если всё хорошо, вы получаете int и можете делать арифметику, сравнения и т.д.

Но практический вывод один: stoi — мостик между миром текста и миром чисел.

Минимальный синтаксис: строка → int

В минимальном виде stoi выглядит так: берём std::string, получаем int. Главное — подключить <string>, потому что и std::string, и std::stoi находятся именно там.

#include <iostream>
#include <string>

int main() {
    std::string text = "42";
    int value = std::stoi(text);

    std::cout << value << '\n';     // 42
}

В этом примере строка "42" идеально подходит для превращения в число. Поэтому std::stoi отрабатывает «без драмы»: вы получаете 42.

Встраиваем stoi в «живой» ввод через getline

Следующий шаг — сделать то, ради чего обычно и нужен stoi: прочитать строку (чаще всего через getline) и превратить её в число.

Здесь важно не торопиться. Мы читаем строку как текст, и только затем говорим: «А теперь попробуем превратить ее в число».

#include <iostream>
#include <string>

int main() {
    std::string line;
    std::getline(std::cin, line);

    int n = std::stoi(line);
    std::cout << "n = " << n << '\n';    // например: n = 15
}

Обратите внимание на психологический момент: программа как будто «вежливо» сначала берёт ввод в безопасном формате (строка), а потом делает шаг интерпретации. Это часто удобнее, чем пытаться читать сразу int, особенно если формат ввода сложнее, чем «одно число без пробелов».

3. Практический пример: мини-анкета

Давайте продолжим условное учебное приложение — консольную анкету. До этого вы уже могли печатать вопросы через std::cout, читать имя через getline, а теперь добавим ввод числа как строки и преобразование через stoi.

Идея простая: спросим имя (строка), спросим год рождения (строка), превратим год рождения в int и посчитаем возраст относительно фиксированного года (пусть будет 2026 — чисто для примера; да, календарь у программы пока «на батарейках»).

#include <iostream>
#include <string>

int main() {
    std::string fullName;
    std::string birthYearText;

    std::cout << "Введите имя и фамилию: ";
    std::getline(std::cin, fullName);

    std::cout << "Введите год рождения (например, 2005): ";
    std::getline(std::cin, birthYearText);

    int birthYear = std::stoi(birthYearText);
    int age = 2026 - birthYear;

    std::cout << "Привет, " << fullName << "!\n";
    std::cout << "Тебе примерно " << age << " лет.\n";
}

Заметьте, как аккуратно мы обошлись без смешивания >> и getline: всё читаем через getline, и это делает поведение ввода предсказуемым. Пока вы новичок, «предсказуемость» обычно важнее, чем «я могу ввести число одной командой cin >>».

4. Поведение stoi: что «прощает» и что делает коварно

Ведущие пробелы и знак числа

Иногда пользователи вводят не идеально. Например, ставят пробелы в начале. Хорошая новость: std::stoi умеет пропускать ведущие пробелы. Плохая новость: это может создать ощущение, что она «всё прощает», а это уже опасная иллюзия.

#include <iostream>
#include <string>

int main() {
    std::string text = "   15";
    int value = std::stoi(text);

    std::cout << value << '\n'; // 15
}

Пробелы в начале не помешали. Это удобно, но одновременно это намекает: stoi — не строгий «парсер по ГОСТу», а скорее алгоритм “попробую понять, что вы имели в виду”.

Частичное преобразование: число в начале, мусор дальше

Вот здесь начинается самое интересное (и самое коварное). Строка может содержать число в начале, а дальше — мусор. И std::stoi часто берёт число из начала и останавливается на первом неподходящем символе.

То есть строка "12kg" вполне может превратиться в число 12.

#include <iostream>
#include <string>

int main() {
    std::string text = "12kg";
    int value = std::stoi(text);

    std::cout << value << '\n'; // 12
}

Почему это важно? Потому что по смыслу "12kg" — это не число, это “число + единица измерения”. Иногда такое поведение полезно (например, вы заранее знаете, что формат именно такой: число в начале, потом суффикс). Но чаще новичок ожидает строгость: «Если там не чистое число — значит ошибка». А stoi может «молча согласиться» и дать вам половинку правды.

Чтобы было наглядно:

Строка ввода Что вы могли ожидать Что часто делает stoi
"42"
42
42
"   42"
ошибка или 42
42
"12kg"
ошибка
12
"kg12"
ошибка ошибка выполнения (часто)
""
ошибка ошибка выполнения (часто)

Слово «часто» здесь не для ухода от ответственности, а как напоминание: точное поведение в деталях — это уже уровень чтения спецификаций и осознанной обработки ошибок. Мы пока на уровне «понимаю идею и вижу ограничения».

5. Ограничения stoi: почему возможна ошибка выполнения

Важный момент: std::stoi — это не магия, а функция, которая может «не справиться».

Если строка не похожа на число (например, "hello", пустая строка "", или что-то слишком большое по модулю для int), то при вызове stoi программа может завершиться с ошибкой выполнения. На уровне ощущений это выглядит так: вы запускаете программу, вводите что-то «не то», и она внезапно прекращает работу (иногда с сообщением, иногда — просто “Runtime error”).

И здесь важно не впасть в крайности.

Первая крайность — паника: «Всё, stoi нельзя использовать». Можно, просто нужно понимать рамку: в этой лекции мы используем stoi как демонстрацию конвертации при корректном вводе.

Вторая крайность — самоуверенность: «Ну раз оно иногда работает даже с "12kg", значит оно умное и само разберётся». Нет. Оно не “поймёт смысл”, оно просто применит свой алгоритм, и если вход выходит за рамки — получите ошибку выполнения.

Особенно часто новички ловят ошибку выполнения в такой ситуации: после std::getline получили пустую строку (например, из-за остатка '\n' после >>), а потом сделали stoi от пустой строки. Пустая строка — не число, и stoi на ней обычно “падает”.

6. Связка getline и оператора >>

Сейчас будет маленький мостик к теме про «остаток '\n'», но без полного повтора. Покажем, почему это важно именно для stoi.

Если вы сначала читаете число через std::cin >>, а потом хотите читать строку через getline, то часто первый getline получает пустую строку. А если после этого вы передадите эту пустую строку в stoi, будет очень грустно.

Поэтому, если формат ввода у вас смешанный, используйте «переходный getline», чтобы съесть остаток строки.

#include <iostream>
#include <string>

int main() {
    int a = 0;
    std::string dummy;
    std::string numberLine;

    std::cin >> a;
    std::getline(std::cin, dummy);       // съели остаток '\n'
    std::getline(std::cin, numberLine);  // читаем строку

    int b = std::stoi(numberLine);
    std::cout << (a + b) << '\n';
}

В рамках нашего уровня это выглядит как правило гигиены: раз уж вы решили конвертировать строку в число через stoi, сначала убедитесь, что вы реально прочитали не пустую и не случайную строку.

7. Конвертация и валидация: не путать

Очень полезно заранее разделить два понятия.

Конвертация — это “у меня уже есть корректная строка с числом, преврати её в int”. Именно это делает stoi в нашем сегодняшнем использовании.

Валидация — это “проверь, что строка действительно является корректным числом, и аккуратно обработай ошибки”. Это отдельная инженерная задача, которая потребует либо более продвинутого ввода, либо обработки ошибок, либо других инструментов стандартной библиотеки. Мы туда пока не лезем: не потому что это «запрещено», а потому что в курсе есть порядок тем, и мы не хотим превращать ранние занятия в «марафон боли».

Поэтому честная рамка лекции такая: std::stoi здесь — демонстрация механики “строка → int” и знакомство с ограничениями.

8. Типичные ошибки при работе со std::stoi

Ошибка №1: воспринимать stoi как «проверку корректности».
Новичок часто думает: «Если stoi вернул число — значит строка корректна». Но строка "12kg" может дать 12, и программа продолжит работать, как будто всё нормально. Это не валидация, это попытка извлечь число из начала строки.

Ошибка №2: передавать в stoi пустую строку после getline.
Пустая строка — нормальный результат getline (пользователь мог нажать Enter, или вы могли случайно прочитать остаток '\n'). Но для stoi пустая строка обычно означает ошибку выполнения. Поэтому “прочитал строку” и “прочитал строку с числом” — это не одно и то же.

Ошибка №3: забыть, что stoi работает с int, а int не бесконечен.
Даже если строка выглядит как число, оно может быть слишком большим по модулю для int. Тогда stoi может привести к ошибке выполнения. На этом этапе достаточно помнить простую мысль: у типов есть диапазоны, и ввод может быть «слишком большим».

Ошибка №4: смешать std::cin >> и std::getline без “переходной строки”, а потом обвинить stoi.
Очень легко перепутать причину и следствие: программа падает на stoi, но настоящая причина в том, что getline прочитал пустую строку из-за оставшегося '\n'. В итоге кажется, что «stoi сломан», хотя сломалась логика ввода.

Ошибка №5: забыть подключить <string>.
Иногда код компилируется в одной среде и не компилируется в другой, и студент начинает подозревать заговор компилятора. На деле std::string и std::stoi живут в заголовке <string>, и лучше подключать его явно, чтобы код был переносимым и понятным.

1
Задача
C++ SELF, 2 уровень, 5 лекция
Недоступна
Плюс десять
Плюс десять
1
Задача
C++ SELF, 2 уровень, 5 лекция
Недоступна
Сдача без кассы
Сдача без кассы
1
Задача
C++ SELF, 2 уровень, 5 лекция
Недоступна
Два способа ввода
Два способа ввода
1
Задача
C++ SELF, 2 уровень, 5 лекция
Недоступна
Цена с суффиксом
Цена с суффиксом
1
Опрос
Целые числа и ввод данных, 2 уровень, 5 лекция
Недоступен
Целые числа и ввод данных
Целые числа, строки и ввод данных
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ