Jak mogę przekonwertować std:: string na int?
Mam szybkie pytanie. Rozglądałem się trochę po Internecie i znalazłem kilka rozwiązań, ale żadne z nich jeszcze nie zadziałało. Patrząc na konwersję łańcucha do int i nie mam na myśli kodów ASCII.
W przypadku szybkiego rozruchu, jesteśmy przekazywani w równaniu jako ciąg znaków. Mamy je rozbić, sformatować poprawnie i rozwiązać równania liniowe. Mówiąc to, nie jestem w stanie przekonwertować ciągu znaków na int.
Wiem, że ciąg będzie w formacie (-5) lub (25) itd. więc to na pewno int. Ale jak to wydobyć ze Sznurka?
Jednym ze sposobów, o którym myślałem, jest uruchomienie pętli for / while przez ciąg znaków, sprawdzenie cyfry, wyodrębnienie wszystkich cyfr po tym, a następnie sprawdzenie, czy nie ma wiodącego' -', jeśli istnieje, pomnóż int przez -1.
Wydaje się to trochę zbyt skomplikowane dla tak małego problemu. Jakieś pomysły?
11 answers
W C++11 jest kilka nowych funkcji konwertujących z std::string
na typ liczby.
Więc zamiast
atoi( str.c_str() )
Możesz użyć
std::stoi( str )
Gdzie str
jest twoją liczbą jako std::string
.
Istnieją wersje dla wszystkich smaków liczb:
long stol(string)
, float stof(string)
, double stod(string)
,...
zobacz http://en.cppreference.com/w/cpp/string/basic_string/stol
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-20 08:53:55
std::istringstream ss(thestring);
ss >> thevalue;
Aby być w pełni poprawnym, należy sprawdzić flagi błędów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 15:26:21
Użyj funkcji atoi do konwersji ciągu znaków na liczbę całkowitą:
string a = "25";
int b = atoi(a.c_str());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-30 21:52:57
Możliwe opcje są opisane poniżej:
1. Pierwsza opcja: 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
Jest to błąd (pokazany również przez cppcheck), ponieważ "scanf bez ograniczeń szerokości pola może zawiesić się z ogromnymi danymi wejściowymi w niektórych wersjach libc" (zobacz tutaj i tutaj ).
2. Druga opcja: 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
}
To rozwiązanie jest krótkie i eleganckie, ale jest dostępne tylko na kompilatorach zgodnych z C++11.
3. Trzecia opcja: 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 ??
Jednak przy takim rozwiązaniu trudno jest odróżnić złe dane wejściowe (patrz tutaj ).
4. Czwarta opcja: Boost ' S 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
}
Jest to jednak tylko wrapper sstream, a dokumentacja sugeruje użycie sstrem dla lepszego zarządzania błędami (zobacz tutaj ).
5. Piąta opcja: strto*()
To rozwiązanie jest bardzo długie, ze względu na zarządzanie błędami, i jest opisane tutaj. Ponieważ żadna funkcja nie zwraca zwykłej liczby całkowitej, konwersja jest potrzebna w przypadku liczby całkowitej (zobacz tutaj , aby dowiedzieć się, jak tę konwersję można osiągnąć).
6. Szósta opcja: 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
Wnioski
Podsumowując, najlepszym rozwiązaniem jest C++11 std::stoi() lub, jako druga opcja, użycie bibliotek Qt. Wszystkie inne rozwiązania są zniechęcane lub wadliwe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-20 15:35:13
A co z wzmocnieniem.Lexical_cast ?
Oto ich przykład:
Poniższy przykład traktuje argumenty linii poleceń jako ciąg danych liczbowych:
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);
}
}
...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-26 11:53:09
Wprawdzie moje rozwiązanie nie zadziała dla liczb ujemnych, ale wyodrębni wszystkie liczby dodatnie z tekstu wejściowego zawierającego liczby całkowite. Używa 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;
}
Tekst wejściowy:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878
Wyjściowe liczby całkowite:
5
25
7987
78
9878
Klasa numeric_only
jest zdefiniowana jako:
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];
}
};
Pełne demo online: http://ideone.com/dRWSj
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 15:36:19
To pewnie trochę przesada, ale
boost::lexical_cast<int>( theString )
powinien do pracy
całkiem dobrze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-09 21:10:41
atoi
jest wbudowaną funkcją, która konwertuje łańcuch znaków na liczbę całkowitą, zakładając, że łańcuch zaczyna się od reprezentacji liczb całkowitych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 15:27:57
W Windows możesz użyć:
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
musisz określić bazę, jeśli chcesz zinterpretować hexdecimal.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-25 12:44:28
To normalnie działa, gdy go używam:
int myint = int::Parse(mystring);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 09:44:49
Jest inny prosty sposób : Załóżmy, że masz postać podobną do c='4'
, dlatego możesz wykonać jeden z następujących kroków:
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 .
Druga droga:
q=c-'0'; the same , character '0' means 48
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-02 08:49:08