Как я могу преобразовать std:: string в int?
просто есть быстрый вопрос. Я посмотрел вокруг в интернете совсем немного, и я нашел несколько решений, но ни один из них еще работал. Глядя на преобразование строки в int, и я не имею в виду ASCII-коды.
для быстрого разбега мы передаем уравнение в виде строки. Мы должны разбить его, правильно отформатировать и решить линейные уравнения. Теперь, говоря это, я не могу преобразовать строку в int.
Я знаю, что строка будет в либо формат (-5) или (25) и т. д. так что это определенно int. Но как нам извлечь из строки?
один из способов, которым я думал, это запустить цикл for/while через строку, проверить цифру, извлечь все цифры после этого, а затем посмотреть, есть ли ведущий' -', если есть, умножьте int на -1.
Это кажется немного более сложным для такой маленькой проблемой, хотя. Есть идеи?
11 ответов:
в C++11 есть некоторые хорошие новые функции преобразования из
std::stringк типу число.так вместо
atoi( str.c_str() )можно использовать
std::stoi( str )здесь
str- Это ваш номер какstd::string.есть версия для всех вкусов чисел:
long stol(string),float stof(string),double stod(string),... смотрите http://en.cppreference.com/w/cpp/string/basic_string/stol
std::istringstream ss(thestring); ss >> thevalue;чтобы быть полностью правильным, Вы хотите проверить флаги ошибок.
используйте функцию atoi для преобразования строки в целое число:
string a = "25"; int b = atoi(a.c_str());
возможные варианты описаны ниже:
1. Первый вариант: sscanf ()
#include <cstdio> #include <string> int i; float f; double d; std::string str; // string -> integer if(sscanf(str.c_str(), "%d", &i) != 1) // error management // string -> float if(sscanf(str.c_str(), "%f", &f) != 1) // error management // string -> double if(sscanf(str.c_str(), "%lf", &d) != 1) // error managementэто ошибка (также показанная cppcheck), потому что "scanf без ограничений ширины поля может аварийно завершить работу с огромными входными данными на некоторых версиях libc" (см. здесь и здесь).
2. Второй вариант: std:: sto*()
#include <iostream> #include <string> int i; float f; double d; std::string str; try { // string -> integer int i = std::stoi(s); // string -> float float f = std::stof(s); // string -> double double d = std::stod(s); } catch (...) { // error management }это решение короткое и элегантное, но это доступно только на компиляторах на C++11 compliants.
3. Третий вариант: sstreams
#include <string> #include <sstream> int i; float f; double d; std::string str; // string -> integer std::istringstream ( str ) >> i; // string -> float std::istringstream ( str ) >> f; // string -> double std::istringstream ( str ) >> d; // error management ??однако, с этим решением трудно отличить плохой ввод (см. здесь).
4. Четвертый вариант: увеличить по lexical_cast
#include <boost/lexical_cast.hpp> #include <string> std::string str; try { int i = boost::lexical_cast<int>( str.c_str()); float f = boost::lexical_cast<int>( str.c_str()); double d = boost::lexical_cast<int>( str.c_str()); } catch( boost::bad_lexical_cast const& ) { // Error management }однако это всего лишь оболочка sstream, и документация предлагает использовать sstrem для лучшего управления ошибками (см. здесь).
5. Пятый вариант: strto*()
это решение очень длинное, из-за управления ошибками, и оно описано здесь. Поскольку ни одна функция не возвращает простой int, преобразование необходимо в случае integer (см. здесь как это преобразование может быть достигнуто).
6. Шестой вариант: Qt
#include <QString> #include <string> bool ok; std::string; int i = QString::fromStdString(str).toInt(&ok); if (!ok) // Error management float f = QString::fromStdString(str).toFloat(&ok); if (!ok) // Error management double d = QString::fromStdString(str).toDouble(&ok); if (!ok) // Error managementвыводы
Подводя итог, лучшим решением является C++11 std:: stoi() или, как второй вариант, использование библиотек Qt. Все остальные решения обескуражены или глючат.
а как же импульс.Lexical_cast?
вот пример:
в следующем примере аргументы командной строки рассматриваются как последовательность числовых данных:
int main(int argc, char * argv[]) { using boost::lexical_cast; using boost::bad_lexical_cast; std::vector<short> args; while(*++argv) { try { args.push_back(lexical_cast<short>(*argv)); } catch(bad_lexical_cast &) { args.push_back(0); } } ... }
по общему признанию, мое решение не будет работать для отрицательных целых чисел, но оно будет извлекать все положительные целые числа из входного текста, содержащего целые числа. Это делает использование
numeric_onlylocale:int main() { int num; std::cin.imbue(std::locale(std::locale(), new numeric_only())); while ( std::cin >> num) std::cout << num << std::endl; return 0; }ввод текста:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878выходные целые числа:
5 25 7987 78 9878класс
numeric_onlyопределено как:struct numeric_only: std::ctype<char> { numeric_only(): std::ctype<char>(get_table()) {} static std::ctype_base::mask const* get_table() { static std::vector<std::ctype_base::mask> rc(std::ctype<char>::table_size,std::ctype_base::space); std::fill(&rc['0'], &rc[':'], std::ctype_base::digit); return &rc[0]; } };полная онлайн-демонстрация:http://ideone.com/dRWSj
Это наверное немного перебор, но
boost::lexical_cast<int>( theString )должен к работе весьма неплохо.
atoi-это встроенная функция, которая преобразует строку в целое число, при условии, что строка начинается с представления целого числа.
В Windows, вы можете использовать:
const std::wstring hex = L"0x13"; const std::wstring dec = L"19"; int ret; if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX, &ret)) { std::cout << ret << "\n"; } if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) { std::cout << ret << "\n"; }
strtol,stringstreamнужно указать базу, если вам нужно интерпретировать hexdecimal.
есть еще один простой способ : предположим, у вас есть персонаж, как
c='4'поэтому вы можете сделать один из следующих шагов :1-й : int q
q=(int) c ; (q is now 52 in ascii table ) . q=q-48; remember that adding 48 to digits is their ascii code .второй способ :
q=c-'0'; the same , character '0' means 48
Comments