Punya pertanyaan cepat. I've melihat sekeliling internet cukup sedikit dan I've menemukan beberapa solusi tetapi tidak satupun dari mereka telah bekerja belum. Melihat mengkonversi string ke int dan saya don't maksud kode ASCII.
Untuk run-down cepat, kami diturunkan di sebuah persamaan sebagai string. Kita harus memecahnya, format dengan benar dan memecahkan persamaan linear. Sekarang, dengan mengatakan bahwa, saya'm tidak mampu mengkonversi string ke int.
Aku tahu bahwa string yang akan di format (-5) atau (25) dll. jadi itu's pasti int. Tapi bagaimana kita mengekstrak dari string?
Salah satu cara saya berpikir menjalankan for/while loop melalui string, periksa digit, ekstrak semua digit setelah itu dan kemudian melihat apakah ada yang terkemuka '-', jika ada, kalikan int dengan -1.
Tampaknya sedikit lebih rumit seperti masalah kecil sekalipun. Ada ide?
Dalam C++11 ada beberapa petobat baru fungsi dari std::string
untuk sejumlah jenis.
Jadi bukan
atoi( str.c_str() )
anda dapat menggunakan
std::stoi( str )
di mana str
ini sebagai std::string
.
Ada versi untuk semua rasa dari angka-angka:
lama stol(string)
, float stof(string)
, double stod(string)
,...
lihat http://en.cppreference.com/w/cpp/string/basic_string/stol
Mungkin pilihan yang dijelaskan di bawah ini:
1. Pilihan pertama: 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
Ini adalah sebuah kesalahan (juga ditunjukkan oleh cppcheck) karena "scanf tanpa lebar field batas-batas yang dapat kecelakaan besar dengan input data pada beberapa versi dari libc" (lihat di sini, dan di sini).
*2. Pilihan kedua: 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
}
Solusi ini lebih pendek dan elegan, tapi itu hanya tersedia pada C++11 compliants compiler.
3. Pilihan ketiga: 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 ??
Namun, dengan solusi ini sulit untuk membedakan antara masukan buruk (lihat di sini).
4. Pilihan keempat: Meningkatkan'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
}
Namun, ini adalah hanya sebuah bungkus sstream, dan dokumentasi menyarankan untuk menggunakan sstrem untuk kesalahan yang lebih baik manajemen (lihat di sini).
*5. Pilihan kelima: strto()**
Solusi ini sangat panjang, karena kesalahan manajemen, dan hal ini dijelaskan di sini. Karena tidak ada fungsi mengembalikan polos int, konversi diperlukan dalam kasus bilangan bulat (lihat di sini untuk cara konversi ini dapat dicapai).
6. Pilihan keenam: 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
Kesimpulan
Menyimpulkan, solusi terbaik adalah C++11 std::stoi() atau, sebagai pilihan kedua, penggunaan perpustakaan Qt. Semua solusi lainnya adalah berkecil hati atau kereta.
Apa tentang Boost.Lexical_cast?
Berikut ini adalah contoh mereka:
berikut ini contoh memperlakukan argumen baris perintah sebagai urutan data numerik:
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);
}
}
...
}
Memang, solusi saya tidak't bekerja untuk bilangan bulat negatif, tapi itu akan mengekstrak semua bilangan bulat positif dari input teks yang berisi bilangan bulat. Itu membuat penggunaan numeric_only
lokal:
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;
}
Input teks:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878
Output bilangan bulat:
5
25
7987
78
9878
Kelas numeric_only
didefinisikan sebagai:
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];
}
};
Online lengkap demo : http://ideone.com/dRWSj
It's mungkin sedikit berlebihan, tapi
boost::lexical_cast<int>( theString )
harus untuk pekerjaan
cukup baik.
Dari http://www.cplusplus.com/reference/string/stoi/
// stoi example
#include <iostream> // std::cout
#include <string> // std::string, std::stoi
int main ()
{
std::string str_dec = "2001, A Space Odyssey";
std::string str_hex = "40c3";
std::string str_bin = "-10010110001";
std::string str_auto = "0x7f";
std::string::size_type sz; // alias of size_t
int i_dec = std::stoi (str_dec,&sz);
int i_hex = std::stoi (str_hex,nullptr,16);
int i_bin = std::stoi (str_bin,nullptr,2);
int i_auto = std::stoi (str_auto,nullptr,0);
std::cout << str_dec << ": " << i_dec << " and [" << str_dec.substr(sz) << "]\n";
std::cout << str_hex << ": " << i_hex << '\n';
std::cout << str_bin << ": " << i_bin << '\n';
std::cout << str_auto << ": " << i_auto << '\n';
return 0;
}
Output:
2001 A Space Odyssey: 2001 dan [A Space Odyssey]
40c3: 16579
-10010110001: -1201
0x7f: 127
Di Windows, anda bisa menggunakan:
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
perlu menentukan pilihan jika anda perlu untuk menafsirkan hexdecimal.
Nah, banyak jawaban, banyak kemungkinan. Apa yang saya hilang di sini adalah beberapa metode universal yang mengkonversi string untuk berbagai C++ integral jenis (short, int, long, bool, ...). Saya datang dengan solusi berikut:
#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;
}
Berikut ini adalah contoh-contoh penggunaan:
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
Mengapa tidak hanya menggunakan stringstream output operator untuk mengkonversi string ke tipe integral? Berikut adalah jawabannya: Let's mengatakan string berisi nilai yang melebihi batas dimaksudkan untuk tipe integral. Untuk examle, pada Wndows 64 max int adalah 2147483647. Let's menetapkan serangkaian nilai max int + 1: string str = "2147483648". Sekarang, ketika mengkonversi string ke int:
stringstream ss(str);
int x;
ss >> x;
x menjadi 2147483647, apa yang pasti sebuah kesalahan: string "2147483648" tidak seharusnya dikonversikan ke int 2147483647. Disediakan fungsi toIntegralType bintik-bintik kesalahan tersebut dan melempar pengecualian.
ll toll(string a){
ll ret=0;
bool minus=false;
for(auto i:a){
if(i=='-'){ minus=true; continue; }
ret*=10;
ret+=(i-'0');
} if(minus) ret*=-1;
return ret;
# ll is defined as, #define ll long long int
# usage: ll a = toll(string("-1234"));
}
Salah satu line versi: panjang n = strtol(s.c_str(), NULL, tempat);
.
(s
adalah string, dan dasar
adalah sebuah int
seperti 2, 8, 10, 16.)
Anda bisa lihat tautan ini untuk rincian lebih lanjut dari strtol
.
Inti idenya adalah untuk menggunakan strtol
fungsi, yang termasuk dalam cstdlib
.
Sejak strtol
hanya menangani dengan char
array, kita perlu mengkonversi string
untuk char
array. Anda bisa lihat tautan ini.
Contoh:
#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;
}
yang akan output:
1111000001011010
61530
f05a
1111000001011010
ada cara mudah lain : misalkan anda memiliki karakter seperti c='4'
oleh karena itu anda dapat melakukan salah satu dari langkah-langkah ini :
1 : int q
q=(int) c ; (q sekarang 52 dalam tabel ascii ) . q=q-48; ingat bahwa menambahkan 48 digit adalah kode ascii .
cara kedua :
q=c-'0'; sama , karakter '0' berarti 48