эквивалент атои

Есть ли функция, которая могла бы заменить atoi в C++. Я провел некоторое исследование и не нашел ничего, что могло бы его заменить, единственными решениями было бы использование cstdlib или его реализация самостоятельно.


person Mansuro    schedule 13.08.2011    source источник
comment
Зачем вам его замена?   -  person Jesus Ramos    schedule 13.08.2011
comment
Я не хочу использовать элементы c в коде C++.   -  person Mansuro    schedule 13.08.2011
comment
неужели так сложно набрать atoi(str.c_str()); ? Также трудно избежать этого, учитывая, что C ++ написан на C, так что .... да   -  person Jesus Ramos    schedule 13.08.2011
comment
ну, рекомендуется не использовать код C в C++   -  person Mansuro    schedule 13.08.2011
comment
Как видите, вы можете использовать boost, проблема в том, что вы только что добавили библиотеку boost в свой проект, чтобы использовать 1 метод. Что хуже использовать функцию C или включить всю библиотеку для 1 функции?   -  person Jesus Ramos    schedule 13.08.2011
comment
@Иисус: atoi небезопасно! Он не обрабатывает недопустимый ввод. Также он может использовать еще много других утилит от boost.   -  person Nawaz    schedule 13.08.2011
comment
Я думаю, было бы лучше использовать atoi, но все же...   -  person Mansuro    schedule 13.08.2011
comment
@NawazNawaz, хорошо, если ваша программа получает неверный ввод, я надеюсь, что вы уже это исправляете. Вы не должны полагаться на функции, чтобы делать много вещей, для которых они никогда не были предназначены.   -  person Jesus Ramos    schedule 13.08.2011
comment
Стандартная библиотека C++ явно содержит стандартную библиотеку C, поэтому <cstdlib> является полностью допустимой частью C++. Скажи std::atoi, если тебе от этого станет легче :-)   -  person Kerrek SB    schedule 13.08.2011
comment
@Jesus: Вот что я говорю, atoi не обрабатывает недопустимый ввод.   -  person Nawaz    schedule 13.08.2011
comment
@Kerrek: То, что стандарт C++ включает <cstdlib>, не означает, что std::atoi безопасен (если вы подразумеваете это в своем комментарии). Stdlib также включает <cstdio>, но это не значит, что нужно использовать std::scanf и std::prinf вместо std::cin и std::cout.   -  person Nawaz    schedule 13.08.2011
comment
@Nawaz, я понимаю это, но ты пытаешься сказать это так, как будто это плохо, хотя на самом деле, если ты утверждаешь, что не обработка всего ввода - это плохо, ты просто обвиняешь в своей проблеме с кодом что-то еще, потому что хочешь функция, которая сделает всю работу за вас. В этом случае все целые числа допустимы, поэтому эта функция не может легко вернуть допустимую ошибку.   -  person Jesus Ramos    schedule 13.08.2011
comment
@Jesus: Я пытаюсь сказать, что boost::lexical_cast выполняет как проверку ввода, так и преобразование. Если вы используете atoi, вам нужно написать код, который уже делает boost::lexical_cast. Кроме того, если вы хотите написать код для проверки того, является ли строка допустимой для atoi или нет, то почему бы не преобразовать ее самостоятельно? Зачем вообще использовать atoi?   -  person Nawaz    schedule 13.08.2011
comment
Я согласен с @Nawaz в том, что у atoi очень плохой интерфейс. strtol является подходящей заменой не потому, что он делает что-то другое — нет, а потому, что у него есть интерфейс, позволяющий проверить, произошло ли успешное преобразование. Я действительно не понимаю аргумент @JesusRamos о том, что вы должны написать больше кода для проверки ввода, прежде чем передавать его в функцию преобразования. Разве написать функцию, которая определяет, может ли строка быть преобразована в число, не так же сложно, как написать функцию, которая выполняет это преобразование? В таком случае, почему бы не использовать библиотечную функцию, которая делает и то, и другое.   -  person CB Bailey    schedule 13.08.2011
comment
@Jesus Ramos: Задача проверки int перед передачей его atoi точно так же сложна, как и сам atoi. На самом деле, несмотря на то, что можно предварительно проверить синтаксис ввода, практически невозможно поймать переполнение без фактического преобразования. По этой причине atoi является мертвой функцией, которая не используется в реальном коде. Практически любой код, использующий atoi, не работает только по этой причине. Преобразование строк в целые числа в языке C всегда выполнялось исключительно strto... функциями. У них нет альтернатив в стандартной библиотеке C.   -  person AnT    schedule 27.08.2013
comment
@Mansuro: ... Другими словами, самый оригинальный вопрос уже совершенно ошибочен. Вы не должны были искать эквивалент atoi, так как вы не должны были использовать atoi в первую очередь. Всегда. Вам нужен эквивалент strto... функций. Хотя эти функции доступны и в C++, лучшим вариантом может быть lexical_cast.   -  person AnT    schedule 27.08.2013


Ответы (6)


Если вы не хотите использовать Boost, C++11 добавил std::stoi для строк. . Подобные методы существуют для всех типов.

std::string s = "123"
int num = std::stoi(s);

В отличие от atoi, если преобразование невозможно, выдается исключение invalid_argument. Кроме того, если значение выходит за пределы диапазона для int, генерируется исключение out_of_range. .

person David Rinck    schedule 27.05.2014
comment
Я все еще ожидаю, что в std::string будут методы to_int и to_long или что-то в этом роде, но я думаю, что это почти так же хорошо. - person Steve Summit; 22.12.2015

boost::lexical_cast — ваш друг

#include <string>
#include <boost/lexical_cast.hpp>

int main()
{
    std::string s = "123";
    try
    {
       int i = boost::lexical_cast<int>(s); //i == 123
    }
    catch(const boost::bad_lexical_cast&)
    {
        //incorrect format   
    }
}
person Armen Tsirunyan    schedule 13.08.2011
comment
Армен: boost::lexical_cast может бросить, поэтому окружите его try-catch, чтобы сделать его более полным. - person Nawaz; 13.08.2011
comment
@Nawaz: я дал ссылку на документацию. В этом случае try-catch не нужен. Но ладно, добавлю. - person Armen Tsirunyan; 13.08.2011

Вы можете использовать функцию Boost boost::lexical_cast‹> следующим образом:

char* numericString = "911";
int num = boost::lexical_cast<int>( numericString );

Дополнительную информацию можно найти здесь (последняя версия Boost 1.47 ). Не забывайте правильно обрабатывать исключения.

person Community    schedule 13.08.2011

Без повышения:
stringstream ss(my_string_with_a_number); int my_res; ss >> my_res;
Примерно так же раздражает, как версия с усилением, но без дополнительной зависимости. Может быть, тратить больше оперативной памяти.

person Torp    schedule 13.08.2011
comment
Boost-версия не раздражает - person Armen Tsirunyan; 13.08.2011
comment
Это зависит от того, нравится ли вам направление, в котором движется С++, или нет :) Но давайте не будем загрязнять этот вопрос. - person Torp; 13.08.2011
comment
@Torp: попробуйте преобразовать std::string s="8978x9". Ваш подход потерпит неудачу, не уведомив вас. С другой стороны, boost::lexical_cast выдаст исключение, и вы об этом узнаете! И повышение не раздражает, как уже сказал @Armen. - person Nawaz; 13.08.2011
comment
@Torp, что вы подразумеваете под тем, нравится ли вам направление, в котором движется С++, это плохое или хорошее направление? - person Mansuro; 13.08.2011
comment
На мой взгляд, это «неуправляемо сложное» направление :) Но, к сожалению, я не знаю лучшей универсальной альтернативы. - person Torp; 14.08.2011
comment
Чтобы решить проблему @Nawaz с возможным сбоем этого метода, вы можете протестировать строковый поток после попытки извлечь что-то еще: char x; if (!(ss >> x)) /*success*/ - person kapace; 13.02.2013
comment
@kapace: Как я уже сказал, если ввод, например, "8978x9", то ss будет читать только 8978, не сообщая вам о проблеме, заключающейся в том, что строка содержит 'x', что является недопустимой цифрой. См. демонстрацию в Интернете - person Nawaz; 13.02.2013
comment
@Nawaz: Хм, это то, что я имел в виду: stacked-crooked.com/ - person kapace; 03.03.2013
comment
@kapace: Это очень тонко. Мне это понравилось. Спасибо :-) - person Nawaz; 03.03.2013

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

Использование Boost Spirit.Qi примерно на порядок быстрее, чем atoi, по крайней мере, в тесты, проведенные Алексом Оттом.

У меня нет эталона, но в последний раз, когда я тестировал его, Boost lexical_cast был примерно на порядок медленнее, чем atoi. Я думаю, причина в том, что он создает строковый поток, что довольно дорого.

Обновление: несколько новых тестов

person Alastair    schedule 13.08.2011
comment
Предположительно atoi не подходит из-за его поведения с недопустимым аргументом (я считаю, что поведение не определено). - person Keith Thompson; 27.08.2013

Вы можете использовать функцию stoi();

#include <string> 
// Need to include the <string> library to use stoi

int main(){

   std::string s = "10";
   int n = stoi(s);

}

Чтобы на самом деле скомпилировать это, вам нужно включить С++ 11, посмотреть в Google, как это сделать (в коде:: блоки это: Настройки -> Компилятор -> «Имейте g++ следовать стандарту языка С++ 11 ISO С++») Если вы компилируете из терминала, вам нужно добавить -std=c++11

g++ -std=c++11 -o program program.cpp
person Mirco De Zorzi    schedule 13.07.2016