Просто задай быстрый вопрос. Я немного поглядел в интернете, и я нашел несколько решений, но никто из них еще не работал. Глядя на преобразование строки в int, и я не имею в виду коды ASCII.
Для быстрого прогона мы передаем уравнение в виде строки. Мы должны сломать его, правильно отформатировать и решить линейные уравнения. Теперь, говоря это, я не могу преобразовать строку в int.
Я знаю, что строка будет в формате (-5) или (25) и т.д., так что это определенно int. Но как мы извлекаем это из строки?
Один из способов, которым я думал, - запустить цикл for/while через строку, проверить цифру, извлечь все цифры после этого, а затем посмотреть, есть ли ведущий "-", если есть, умножить int на -1.
Похоже, что для такой маленькой проблемы это немного сложнее. Любые идеи?
В С++ 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
"11x"
в целое число 11
.
std::istringstream ss(thestring);
ss >> thevalue;
Чтобы быть полностью корректным, вы захотите проверить флаги ошибок.
-5
из (-5)
.
используйте функцию atoi для преобразования строки в целое число:
string a = "25";
int b = atoi(a.c_str());
atoi
. strtol
делает все, что делает atoi
, но лучше, и терпит неудачу безопасно.
Возможные варианты описаны ниже:
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
}
Это решение является коротким и элегантным, но доступно только на компиляторах С++ 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. Четвертый вариант: Boost 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, требуется преобразование в случае целого числа (см. здесь, как это может быть достигнуто).
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
Выводы
Подводя итоги, лучшим решением является С++ 11 std:: stoi() или, как второй вариант, использование библиотек Qt. Все другие решения обескуражены или ошибочны.
Как насчет Boost.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_only
locale:
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 )
должен работать
довольно хорошо.
theString&
? Что такое &
?
boost::lexical_cast<int>( theString )
(где theString
- имя переменной, содержащей строку, которую вы хотите преобразовать в int
).
В 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.
atoi
- встроенная функция, которая преобразует строку в целое число, предполагая, что строка начинается с целочисленного представления.
atoi
, используйте вместо этого strtol
.
long n = strtol(s.c_str(), NULL, base);
версия: long n = strtol(s.c_str(), NULL, base);
,
(s
это строка, а base
это int
такой как 2, 8, 10, 16.)
Вы можете обратиться к этой ссылке для более подробной информации о strtol
.
Основная идея заключается в том, чтобы использовать функцию strtol
, которая включена в cstdlib
.
Поскольку strtol
только с массивом char
, нам нужно преобразовать string
в массив char
. Вы можете обратиться к этой ссылке.
Пример:
#include <iostream>
#include <string> // string type
#include <bitset> // bitset type used in the output
int main(){
s = "1111000001011010";
long t = strtol(s.c_str(), NULL, 2); // 2 is the base which parse the string
cout << s << endl;
cout << t << endl;
cout << hex << t << endl;
cout << bitset<16> (t) << endl;
return 0;
}
который выведет:
1111000001011010
61530
f05a
1111000001011010
Ну, много ответов, много возможностей. Здесь мне не хватает универсального метода, который преобразует строку в различные целочисленные типы C++ (short, int, long, bool,...). Я придумал следующее решение:
#include<sstream>
#include<exception>
#include<string>
#include<type_traits>
using namespace std;
template<typename T>
T toIntegralType(const string &str) {
static_assert(is_integral<T>::value, "Integral type required.");
T ret;
stringstream ss(str);
ss >> ret;
if ( to_string(ret) != str)
throw invalid_argument("Can't convert " + str);
return ret;
}
Вот примеры использования:
string str = "123";
int x = toIntegralType<int>(str); // x = 123
str = "123a";
x = toIntegralType<int>(str); // throws exception, because "123a" is not int
str = "1";
bool y = toIntegralType<bool>(str); // y is true
str = "0";
y = toIntegralType<bool>(str); // y is false
str = "00";
y = toIntegralType<bool>(str); // throws exception
Почему бы просто не использовать оператор вывода stringstream для преобразования строки в целочисленный тип? Вот ответ: допустим, строка содержит значение, которое превышает предел для целочисленного типа. Например, в Wndows 64 max int равно 2147483647. Давайте присвоим строке значение max int + 1: string str = "2147483648". Теперь при преобразовании строки в int:
stringstream ss(str);
int x;
ss >> x;
x становится 2147483647, что определенно является ошибкой: строка "2147483648" не должна была быть преобразована в int 2147483647. Предоставленная функция toIntegralType обнаруживает такие ошибки и выдает исключение.
существует еще один простой способ: предположим, что у вас есть символ типа c='4'
, поэтому вы можете сделать один из следующих шагов:
1st: 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
string
в int
а не из char
в string
.
Это нормально работает, когда я его использую:
int myint = int::Parse(mystring);
atoi()
?