Saya mengalami sedikit kesulitan dalam mencoba menulis fungsi yang memeriksa apakah suatu string adalah angka. Untuk permainan yang saya tulis, saya hanya perlu memeriksa apakah baris dari file yang saya baca adalah angka atau tidak (saya akan tahu apakah ini adalah parameter dengan cara ini). Saya menulis fungsi di bawah ini yang saya percaya berfungsi dengan baik (atau saya tidak sengaja diedit untuk menghentikannya atau saya menderita skizofrenia atau Windows adalah skizofrenia):
bool isParam (string line)
{
if (isdigit(atoi(line.c_str())))
return true;
return false;
}
c++
visual-c++
Brendan Weinstein
sumber
sumber
if (expr) return true; return false;
! Cukup tulisreturn expr;
.if (expr) return expr; else return expr;
,if (expr == true)
,(if expr != false)
, atauif ((expr == true) == true)
. Mereka semua memperkenalkan kompleksitas yang tidak menguntungkan penulis, pembaca, atau penyusun kode. Penghapusan kerumitan yang tidak perlu bukanlah jalan pintas; itu kunci untuk menulis perangkat lunak yang lebih baik.Jawaban:
Cara paling efisien adalah dengan mengulangi string sampai Anda menemukan karakter non-digit. Jika ada karakter non-digit, Anda dapat menganggap string bukan angka.
Atau jika Anda ingin melakukannya dengan cara C ++ 11:
Seperti yang ditunjukkan dalam komentar di bawah, ini hanya berfungsi untuk bilangan bulat positif. Jika Anda perlu mendeteksi bilangan bulat atau pecahan negatif, Anda harus menggunakan solusi berbasis pustaka yang lebih kuat. Meskipun, menambahkan dukungan untuk bilangan bulat negatif cukup sepele.
sumber
!s.empty() && s.find_first_not_of("0123456789") == std::string::npos;
untuk C ++ 03 one-liner.int
. Ini hanya mengidentifikasi apakah suatu string terdiri dari digit angka. Tidak masalah berapa lama talinya.<string>
<algorithm>
dan<cctype>
membuat contoh C ++ 11 berfungsi.Mengapa menemukan kembali roda? Pustaka standar C (tersedia dalam C ++ juga) memiliki fungsi yang melakukan ini:
Jika Anda ingin menangani pecahan atau notasi ilmiah, gunakan
strtod
saja (Anda akan mendapatkandouble
hasilnya).Jika Anda ingin memperbolehkan konstanta heksadesimal dan oktal dalam gaya C / C ++ (
"0xABC"
), maka buatlah parameter terakhir0
sebagai gantinya.Fungsi Anda kemudian dapat ditulis sebagai
sumber
atoi
seperti yang digunakan dalam pertanyaan, apakah ini juga).p
akan ditetapkannullptr
jikastrtol
berhasil, bukan? Bukan itu yang saya lihat :(p
akan menunjuk ke NUL yang mengakhiri string. Jadip != 0
dan*p == 0
.Dengan kompiler C ++ 11, untuk bilangan bulat non-negatif saya akan menggunakan sesuatu seperti ini (perhatikan
::
bukanstd::
):http://ideone.com/OjVJWh
sumber
Anda dapat melakukannya dengan cara C ++ dengan boost :: lexical_cast. Jika Anda benar-benar bersikeras untuk tidak menggunakan dorongan, Anda bisa memeriksa apa yang dilakukannya dan melakukannya. Sederhana saja.
sumber
try{} catch{}
ide yang bagus? Haruskah kita menghindarinya sebanyak mungkin?Saya hanya ingin melemparkan ide ini yang menggunakan iterasi tetapi beberapa kode lain melakukan iterasi:
Ini tidak kuat seperti seharusnya ketika memeriksa titik desimal atau tanda minus karena memungkinkan ada lebih dari satu dan di setiap lokasi. Hal yang baik adalah bahwa itu adalah satu baris kode dan tidak memerlukan perpustakaan pihak ketiga.
Ambil '.' dan '-' jika hanya bilangan bulat positif yang diizinkan.
sumber
std::string
, gunakanfind_first_not_of
fungsi anggotanya.Saya menyarankan pendekatan regex. Pertandingan-regex penuh (misalnya, menggunakan boost :: regex ) dengan
akan menunjukkan apakah string adalah angka atau bukan. Ini termasuk angka positif dan negatif, bilangan bulat serta desimal.
Variasi lainnya:
(hanya positif)
(hanya bilangan bulat)
(hanya bilangan bulat positif)
sumber
std::regex
dengan gcc 4.7, gcc 4.8 - mereka berdua membuangstd::regex_error
tanda-tanda[
di regexp, bahkan untuk "[abc]" yang tidak bersalah (apakah saya melakukan itu salah?). Dentang-3.4 tidak menyadari<regex>
sama sekali. Ngomong-ngomong, ini sepertinya jawaban paling jago, +1.Berikut cara lain untuk melakukannya menggunakan
<regex>
perpustakaan:sumber
Dengan solusi ini Anda dapat memeriksa semuanya, mulai dari negatif ke angka positif dan bahkan angka mengambang. Ketika Anda mengubah tipe
num
ke integer Anda akan mendapatkan kesalahan jika string berisi titik.Buktikan: Program C ++
sumber
Saya telah menemukan kode berikut ini sebagai yang paling kuat (c ++ 11). Ini menangkap bilangan bulat dan mengapung.
sumber
using namespace std;
itu tidak perlu.Berikut adalah solusi untuk memeriksa bilangan bulat positif:
sumber
Coba ini:
sumber
Brendan ini
hampir ok.
dengan asumsi string yang dimulai dengan 0 adalah angka, tambahkan saja tanda centang untuk kasus ini
ofc "123hello" akan kembali benar seperti yang dicatat Tony D.
sumber
Yang paling sederhana yang dapat saya pikirkan di c ++
Contoh kode kerja: https://ideone.com/nRX51Y
sumber
Solusi saya menggunakan C ++ 11 regex (
#include <regex>
), dapat digunakan untuk pemeriksaan yang lebih tepat, sepertiunsigned int
,double
dll:Anda dapat menemukan kode ini di http://ideone.com/lyDtfi , ini dapat dengan mudah dimodifikasi untuk memenuhi persyaratan.
sumber
Solusi berdasarkan komentar oleh kbjorklu adalah:
Seperti halnya jawaban David Rector, tidak kuat untuk merangkai dengan beberapa titik atau tanda minus, tetapi Anda dapat menghapus karakter-karakter itu hanya untuk memeriksa bilangan bulat.
Namun, saya sebagian untuk solusi, berdasarkan solusi Ben Voigt , menggunakan
strtod
cstdlib untuk melihat nilai desimal, notasi ilmiah / teknik, notasi heksidecimal (C ++ 11), atau bahkan INF / INFINITY / NAN (C ++ 11) adalah:sumber
Kami dapat menggunakan kelas stringstream .
sumber
Menggunakan
<regex>
. Kode ini telah diuji!sumber
Setelah membaca dokumentasi sedikit lebih lama, saya menemukan jawaban yang mendukung kebutuhan saya, tetapi mungkin tidak akan membantu orang lain. Ini dia (tanpa pengembalian yang mengganggu benar dan mengembalikan pernyataan palsu :-))
sumber
0
, Anda akan mendapatkan false-negative.Saya pikir ungkapan reguler ini harus menangani hampir semua kasus
sehingga Anda dapat mencoba fungsi berikut yang dapat bekerja dengan keduanya (Unicode dan ANSI)
sumber
Untuk Memvalidasi Ganda:
}
Untuk Memvalidasi Ints (Dengan Negatif)
}
Untuk Memvalidasi Para Unsigned Ints
}
sumber
cara kerjanya: stringstream >> overload dapat mengonversi string ke berbagai tipe aritmatika yang dilakukannya dengan membaca karakter secara berurutan dari stringstream (ss dalam kasus ini) hingga kehabisan karakter ATAU karakter berikutnya tidak memenuhi kriteria untuk disimpan ke dalam tipe variabel tujuan.
Contoh 1:
contoh2:
example3:
penjelasan variabel "sampah":
mengapa tidak mengecek apakah ekstraksi ke dalam double saya memiliki nilai yang valid dan kemudian mengembalikan true jika benar?
perhatikan example3 di atas masih akan berhasil membaca angka 11 ke dalam variabel my_number bahkan jika string input adalah "11ABCD" (yang bukan angka).
untuk menangani kasus ini kita dapat melakukan ekstraksi lain ke dalam variabel string (yang saya namakan sampah) yang dapat membaca apa pun yang mungkin telah tersisa di buffer string setelah ekstraksi awal ke dalam variabel tipe ganda. Jika ada sesuatu yang tersisa itu akan dibaca menjadi "sampah" yang berarti string penuh yang dilewati bukanlah angka (itu hanya dimulai dengan satu). dalam hal ini kami ingin mengembalikan false;
penjelasan "0" yang disebutkan sebelumnya:
mencoba mengekstraksi karakter tunggal menjadi ganda akan gagal (mengembalikan 0 ke dalam ganda kami) tetapi masih akan memindahkan posisi buffer string ke setelah karakter. Dalam hal ini pembacaan sampah kami akan kosong yang akan menyebabkan fungsi salah mengembalikan benar. untuk menyiasatinya, saya menambahkan 0 ke string sehingga jika misalnya string yang dilewatkan adalah "a" maka akan diubah menjadi "0a" sehingga 0 akan diekstraksi menjadi dobel dan "a" diekstraksi menjadi sampah.
mengawali a 0 tidak akan memengaruhi nilai angka sehingga angka tersebut masih akan diekstraksi dengan benar ke dalam variabel ganda kami.
sumber
untuk memeriksa apakah string adalah bilangan bulat atau floating point atau lebih Anda bisa menggunakan:
sumber
Namun jawaban lain, yang menggunakan
stold
(meskipun Anda juga bisa menggunakanstof
/stod
jika Anda tidak memerlukan presisi).sumber
Seperti yang diungkapkan kepada saya dalam jawaban untuk pertanyaan terkait saya, saya merasa Anda harus menggunakan boost :: conversion :: try_lexical_convert
sumber
Coba ini:
sumber
Anda dapat menguji apakah string dapat dikonversi ke integer dengan menggunakan boost :: lexical_cast . Jika melempar pengecualian bad_lexical_cast maka string tidak dapat dikonversi, jika tidak maka bisa.
Lihat contoh program pengujian seperti di bawah ini:
Eksekusi sampel:
sumber
Beberapa bulan yang lalu, saya menerapkan cara untuk menentukan apakah ada string bilangan bulat, heksadesimal atau ganda.
Kemudian dalam program Anda, Anda dapat dengan mudah mengkonversi angka dalam fungsi tipenya jika Anda melakukan hal berikut,
Anda dapat menyadari bahwa fungsi tersebut akan mengembalikan 0 jika nomor tersebut tidak terdeteksi. Angka 0 dapat dianggap false (seperti boolean).
sumber
Saya mengusulkan konvensi sederhana:
Jika konversi ke ASCII adalah> 0 atau dimulai dengan 0 maka itu adalah angka. Itu tidak sempurna tetapi cepat.
Sesuatu seperti ini:
sumber
Fungsi ini menangani semua kemungkinan kasus:
sumber
Bisakah Anda menggunakan kode pengembalian sscanf untuk menentukan apakah itu int?
sumber