@ Mat: itu akan menjadi ide yang baik untuk lebih konkret. bertanya tentang generalisasi hanya mengundang jawaban umum yang tidak berlaku atau bahkan benar untuk tugas Anda. perlu diingat, ketika Anda harus bertanya, Anda mungkin tidak cukup tahu untuk menggeneralisasi dengan benar.
Ceria dan hth. - Alf
@Alf P. Steinbach: Pertanyaan aslinya tidak jelas tentang bahasa yang mana. Dengan kata kunci cdan c++, saya pikir jawaban yang bertentangan dengan kedua bahasa itu masuk akal.
Matt Joiner
8
Dari pengalaman saya yang luas di forum teknis lain, intuisi saya adalah bahwa OP benar-benar berarti "bagaimana cara saya mengambil representasi tekstual dari suatu angka (dalam basis 10) dan mengonversinya ke nomor yang sesuai?" Secara umum, neophytes C dan C ++ biasanya memiliki ide-ide yang sangat kabur tentang bagaimana teks bekerja dalam bahasa-bahasa tersebut dan apa chararti sebenarnya.
Karl Knechtel
3
@KarlKnechtel: Jika itu benar (saya berikan sekitar 50/50 karena banyak tutorial awal juga mendorong mendapatkan nilai ASCII dari chars, meskipun ASCII tidak mencakup jangkauan penuh), OP perlu kejelasan - tapi itu dupe dari stackoverflow.com/questions/439573/… .
Fred Nurk
3
OP punya waktu tiga jam untuk mengklarifikasi pertanyaan ini dan gagal melakukannya. Karena itu, tidak ada cara untuk mengetahui apa yang sebenarnya ditanyakan. Memilih untuk menutup.
sbi
Jawaban:
552
Tergantung pada apa yang ingin Anda lakukan:
untuk membaca nilai sebagai kode ascii, Anda dapat menulis
char a ='a';int ia =(int)a;/* note that the int cast is not necessary -- int ia = a would suffice */
untuk mengkonversi karakter '0' -> 0, '1' -> 1, dll, Anda dapat menulis
char a ='4';int ia = a -'0';/* check here if ia is bounded by 0 and 9 */
Penjelasan : a - '0'sama dengan ((int)a) - ((int)'0'), yang berarti nilai-nilai ascii karakter dikurangi satu sama lain. Karena 0datang langsung sebelum 1di tabel ascii (dan seterusnya sampai 9), perbedaan antara keduanya memberikan angka yang amewakili karakter .
@KshitijBanerjee Itu bukan ide yang baik karena dua alasan: itu memberi Anda angka negatif untuk karakter ascii sebelum '0' (seperti &-> -10), dan itu memberi Anda angka yang lebih besar dari 10 (seperti x-> 26)
SheetJS
2
int ia = a - '0' - itulah yang Anda butuhkan
funk
5
@ kevin001 Jika Anda ingin mengonversi char ke int dan sebuah karakter '1'memberikan nomor ascii yang tidak 1, Anda perlu menghapus offset '0'untuk menyetel kembali untuk menghitungnya mulai 0-9. Angka berturut-turut 1-9 berdekatan dalam angka integer ascii.
krisdestruction
Tidak diperlukan pemeran / diinginkan
Craig Estey
97
Nah, dalam kode ASCII, angka (digit) mulai dari 48 . Yang perlu Anda lakukan adalah:
@chad: Tidak hanya lebih mudah dibaca, tetapi juga lebih portabel. C dan C ++ tidak menjamin representasi ASCII, tetapi mereka menjamin bahwa representasi apa pun yang digunakan, representasi dari 10 digit desimal bersebelahan dan dalam urutan numerik.
Ben Voigt
Satu-satunya hal yang saya akan ubah adalah untuk mengaktifkan 48, yang tampaknya sedikit "ajaib" untuk'0'
ArielGro
59
C dan C ++ selalu mempromosikan tipe setidaknya int. Selanjutnya literal karakter bertipe intC dan charC ++.
Anda dapat mengonversi charjenis hanya dengan menetapkan ke int.
Anda juga bisa menggunakan unary yang sangat kurang dihargai operator+()untuk tujuan ini.
Cubbi
24
-1 Jawabannya tidak benar untuk satu-satunya interpretasi bermakna dari pertanyaan. (Kode int a = c;) ini akan menyimpan nilai negatif apa pun, yang tidak bisa ditangani oleh fungsi pustaka standar C. Fungsi pustaka standar C menetapkan standar untuk artinya menangani charnilai sebagai int.
Ceria dan hth. - Alf
6
@ Matt: Saya menyimpan downvote. Saya akan memperkuatnya jika memungkinkan! Penafsiran pertanyaan yang Anda dan orang lain anggap tidak bermakna, karena terlalu sepele, dan karena untuk kombinasi jenis OP tertentu ada masalah praktis yang tidak terlalu sepele yang sangat penting. Saran yang Anda berikan secara langsung berbahaya bagi pemula. Kemungkinan besar akan menghasilkan Perilaku Tidak Terdefinisi untuk program mereka yang menggunakan fungsi klasifikasi karakter perpustakaan standar C. Ref ref. untuk jawaban @ Sayam, ia telah menghapus jawaban itu.
Ceria dan hth. - Alf
3
-1 karena salah: isupper () akan memiliki hasil yang tidak ditentukan jika melewati karakter highbit 1252.
Chris Becke
1
Apa yang Anda maksud dengan "selalu berpromosi"? Nilai dipromosikan selama konversi implisit, jenis parameter tertentu yang lewat (mis., Ke fungsi varargs), dan ketika operator harus membuat operan jenis yang kompatibel. Tetapi ada saat-saat ketika nilai tidak dipromosikan (seperti jika saya meneruskan char ke fungsi mengharapkan char), jika tidak kita tidak akan memiliki tipe yang lebih kecil dari int.
Adrian McCarthy
31
char hanyalah integer 1 byte. Tidak ada yang ajaib dengan tipe char! Sama seperti Anda dapat menetapkan pendek ke int, atau int untuk panjang, Anda dapat menetapkan char ke int.
Ya, nama tipe data primitif adalah "char", yang menyiratkan bahwa itu hanya boleh berisi karakter. Namun pada kenyataannya, "char" hanyalah pilihan nama yang buruk untuk membingungkan semua orang yang mencoba untuk belajar bahasa. Nama yang lebih baik untuk itu adalah int8_t, dan Anda dapat menggunakan nama itu, jika kompiler Anda mengikuti standar C terbaru.
Meskipun tentu saja Anda harus menggunakan tipe char saat melakukan penanganan string, karena indeks tabel ASCII klasik cocok dalam 1 byte. Namun Anda bisa melakukan penanganan string dengan int reguler juga, meskipun tidak ada alasan praktis di dunia nyata mengapa Anda ingin melakukannya. Misalnya, kode berikut akan berfungsi dengan sempurna:
int str[]={'h','e','l','l','o','\0'};for(i=0; i<6; i++){
printf("%c", str[i]);}
Anda harus menyadari bahwa karakter dan string hanyalah angka, seperti yang lainnya di komputer. Ketika Anda menulis 'a' dalam kode sumber, kode itu sudah diproses lebih dulu ke angka 97, yang merupakan konstanta bilangan bulat.
Jadi, jika Anda menulis ekspresi seperti
char ch ='5';
ch = ch -'0';
ini sebenarnya setara dengan
char ch =(int)53;
ch = ch -(int)48;
yang kemudian melalui promosi integer bahasa C
ch =(int)ch -(int)48;
dan kemudian dipotong ke arang agar sesuai dengan tipe hasil
ch =(char)((int)ch -(int)48);
Ada banyak hal halus seperti ini terjadi di antara garis, di mana char secara implisit diperlakukan sebagai int.
Karena pertanyaan tidak ditandai ascii, Anda tidak boleh mengasumsikan penyandian khusus apa pun. Pengaturan charsama dengan int8_tsalah karena itu kemungkinan bisa sama uint8_tatau uint24_t.
Roland Illig
1
@RolandIllig Tidak, a charselalu 1 byte dan jika jenis int8_t/ uint8_tada pada sistem yang diberikan (yang sangat mungkin), mereka akan dapat cocok dengan hasil dari char, karena itu akan menjadi 8 bit. Pada sistem yang sangat eksotis seperti berbagai DSP usang, charakan ada 16 bit dan uint8_ttidak akan ada. Menulis kode untuk kompatibilitas dengan DSP usang adalah omong kosong, seperti menulis untuk kompatibilitas dengan komplemen seseorang atau sistem sign & magnitude. Buang-buang waktu, karena sistem seperti itu nyaris tidak ada di dunia nyata.
Lundin
18
(Jawaban ini membahas sisi C ++, tetapi masalah ekstensi tanda ada di C juga.)
Penanganan ketiga charjenis ( signed, unsigned, dan char) lebih halus daripada pertama kali muncul. Nilai dalam kisaran 0 hingga SCHAR_MAX(yaitu 127 untuk 8-bit char) mudah:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;int n = c;
Tetapi, ketika somevalueberada di luar rentang itu, hanya melalui unsigned charmemberi Anda hasil yang konsisten untuk nilai-nilai "sama" chardi ketiga jenis:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;// Might not be true: int(c) == int(sc) and int(c) == int(uc).int nc =(unsignedchar)c;int nsc =(unsignedchar)sc;int nuc =(unsignedchar)uc;// Always true: nc == nsc and nc == nuc.
Ini penting ketika menggunakan fungsi dari ctype.h , seperti isupperatau toupper, karena ekstensi tanda:
char c = negative_char;// Assuming CHAR_MIN < 0.int n = c;bool b = isupper(n);// Undefined behavior.
Perhatikan bahwa konversi melalui int adalah implisit; ini memiliki UB yang sama:
char c = negative_char;bool b = isupper(c);
Untuk memperbaiki ini, masuk melalui unsigned char, yang mudah dilakukan dengan pembungkus ctype.h fungsi melalui safe_ctype :
template<int(&F)(int)>int safe_ctype(unsignedchar c){return F(c);}//...char c = CHAR_MIN;bool b = safe_ctype<isupper>(c);// No UB.
std::string s ="value that may contain negative chars; e.g. user input";
std::transform(s.begin(), s.end(), s.begin(),&safe_ctype<toupper>);// Must wrap toupper to eliminate UB in this case, you can't cast// to unsigned char because the function is called inside transform.
Ini berfungsi karena setiap fungsi yang mengambil salah satu dari ketiga tipe char juga dapat mengambil dua tipe char lainnya. Ini mengarah ke dua fungsi yang dapat menangani salah satu jenis:
int ord(char c){return(unsignedchar)c;}char chr(int n){assert(0<= n);// Or other error-/sanity-checking.assert(n <= UCHAR_MAX);return(unsignedchar)n;}// Ord and chr are named to match similar functions in other languages// and libraries.
ord(c)selalu memberi Anda nilai non-negatif - bahkan ketika melewati negatif charatau negatif signed char- dan chrmengambil nilai apa pun ordmenghasilkan dan memberikan kembali yang sama persis char.
Dalam prakteknya, saya mungkin hanya akan melemparkan unsigned charalih-alih menggunakan ini, tetapi mereka membungkus gips secara ringkas, menyediakan tempat yang nyaman untuk menambahkan pengecekan kesalahan untuk int-to- char, dan akan lebih pendek dan lebih jelas ketika Anda perlu menggunakannya beberapa kali dalam jarak dekat.
Itu semacam tergantung pada apa yang Anda maksud dengan "mengkonversi".
Jika Anda memiliki serangkaian karakter yang mewakili integer, seperti "123456", maka ada dua cara khas untuk melakukannya di C: Gunakan konversi tujuan khusus seperti atoi () atau strtol () , atau sscanf tujuan umum () . C ++ (yang benar-benar bahasa yang berbeda menyamar sebagai peningkatan) menambahkan stringstreams ketiga.
Jika Anda ingin pola bit yang tepat di salah satu intvariabel Anda diperlakukan sebagai char, itu lebih mudah. Dalam C tipe integer yang berbeda benar-benar lebih merupakan keadaan pikiran daripada "tipe" yang terpisah. Hanya mulai menggunakannya chardi mana diminta, dan Anda harus baik-baik saja. Anda mungkin perlu konversi eksplisit untuk membuat kompilator berhenti merengek pada kesempatan, tetapi semua yang harus dilakukan adalah menjatuhkan bit tambahan melewati 256.
Saya benar-benar memiliki nullketerampilan dalam C, tetapi untuk penguraian sederhana:
char* something ="123456";int number = parseInt(something);
... ini bekerja untuk saya:
int parseInt(char* chars){int sum =0;int len = strlen(chars);for(int x =0; x < len; x++){int n = chars[len -(x +1)]-'0';
sum = sum + powInt(n, x);}return sum;}int powInt(int x,int y){for(int i =0; i < y; i++){
x *=10;}return x;}
Kode ini dengan cepat memanggil perilaku tidak terdefinisi dan karenanya tidak cocok untuk disalin dan ditempel. (int overflow)
Roland Illig
4
Mungkin Anda menginginkan konversi ini untuk menggunakan fungsi-fungsi dari pustaka standar C.
Dalam hal ini, lakukan (sintaks C ++)
typedefunsignedcharUChar;char myCppFunc(char c ){returnchar( someCFunc(UChar( c )));}
Ekspresi UChar( c )dikonversi ke unsigned charuntuk menghilangkan nilai-nilai negatif, yang, kecuali untuk EOF, tidak didukung oleh fungsi C.
Kemudian hasil dari ungkapan itu digunakan sebagai argumen aktual untuk intargumen formal. Di mana Anda mendapatkan promosi otomatis int. Anda dapat juga menulis langkah terakhir secara eksplisit, seperti int( UChar( c ) ), tetapi secara pribadi saya menemukan itu terlalu bertele-tele.
Saya mengalami masalah dalam mengubah array char seperti "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"menjadi nilai integer aktual yang akan dapat diwakili oleh `7C 'sebagai satu nilai heksadesimal. Jadi, setelah mencari bantuan, saya membuat ini, dan berpikir itu akan keren untuk dibagikan.
Ini memisahkan string char menjadi bilangan bulat kanannya, dan mungkin bermanfaat bagi lebih banyak orang daripada hanya saya;)
c
danc++
, saya pikir jawaban yang bertentangan dengan kedua bahasa itu masuk akal.char
arti sebenarnya.Jawaban:
Tergantung pada apa yang ingin Anda lakukan:
untuk membaca nilai sebagai kode ascii, Anda dapat menulis
untuk mengkonversi karakter
'0' -> 0
,'1' -> 1
, dll, Anda dapat menulisPenjelasan :
a - '0'
sama dengan((int)a) - ((int)'0')
, yang berarti nilai-nilai ascii karakter dikurangi satu sama lain. Karena0
datang langsung sebelum1
di tabel ascii (dan seterusnya sampai9
), perbedaan antara keduanya memberikan angka yanga
mewakili karakter .sumber
&
-> -10), dan itu memberi Anda angka yang lebih besar dari 10 (sepertix
-> 26)'1'
memberikan nomor ascii yang tidak1
, Anda perlu menghapus offset'0'
untuk menyetel kembali untuk menghitungnya mulai 0-9. Angka berturut-turut 1-9 berdekatan dalam angka integer ascii.Nah, dalam kode ASCII, angka (digit) mulai dari 48 . Yang perlu Anda lakukan adalah:
sumber
'0'
C dan C ++ selalu mempromosikan tipe setidaknya
int
. Selanjutnya literal karakter bertipeint
C danchar
C ++.Anda dapat mengonversi
char
jenis hanya dengan menetapkan keint
.sumber
operator+()
untuk tujuan ini.int a = c;
) ini akan menyimpan nilai negatif apa pun, yang tidak bisa ditangani oleh fungsi pustaka standar C. Fungsi pustaka standar C menetapkan standar untuk artinya menanganichar
nilai sebagaiint
.char hanyalah integer 1 byte. Tidak ada yang ajaib dengan tipe char! Sama seperti Anda dapat menetapkan pendek ke int, atau int untuk panjang, Anda dapat menetapkan char ke int.
Ya, nama tipe data primitif adalah "char", yang menyiratkan bahwa itu hanya boleh berisi karakter. Namun pada kenyataannya, "char" hanyalah pilihan nama yang buruk untuk membingungkan semua orang yang mencoba untuk belajar bahasa. Nama yang lebih baik untuk itu adalah int8_t, dan Anda dapat menggunakan nama itu, jika kompiler Anda mengikuti standar C terbaru.
Meskipun tentu saja Anda harus menggunakan tipe char saat melakukan penanganan string, karena indeks tabel ASCII klasik cocok dalam 1 byte. Namun Anda bisa melakukan penanganan string dengan int reguler juga, meskipun tidak ada alasan praktis di dunia nyata mengapa Anda ingin melakukannya. Misalnya, kode berikut akan berfungsi dengan sempurna:
Anda harus menyadari bahwa karakter dan string hanyalah angka, seperti yang lainnya di komputer. Ketika Anda menulis 'a' dalam kode sumber, kode itu sudah diproses lebih dulu ke angka 97, yang merupakan konstanta bilangan bulat.
Jadi, jika Anda menulis ekspresi seperti
ini sebenarnya setara dengan
yang kemudian melalui promosi integer bahasa C
dan kemudian dipotong ke arang agar sesuai dengan tipe hasil
Ada banyak hal halus seperti ini terjadi di antara garis, di mana char secara implisit diperlakukan sebagai int.
sumber
ascii
, Anda tidak boleh mengasumsikan penyandian khusus apa pun. Pengaturanchar
sama denganint8_t
salah karena itu kemungkinan bisa samauint8_t
atauuint24_t
.char
selalu 1 byte dan jika jenisint8_t
/uint8_t
ada pada sistem yang diberikan (yang sangat mungkin), mereka akan dapat cocok dengan hasil darichar
, karena itu akan menjadi 8 bit. Pada sistem yang sangat eksotis seperti berbagai DSP usang,char
akan ada 16 bit danuint8_t
tidak akan ada. Menulis kode untuk kompatibilitas dengan DSP usang adalah omong kosong, seperti menulis untuk kompatibilitas dengan komplemen seseorang atau sistem sign & magnitude. Buang-buang waktu, karena sistem seperti itu nyaris tidak ada di dunia nyata.(Jawaban ini membahas sisi C ++, tetapi masalah ekstensi tanda ada di C juga.)
Penanganan ketiga
char
jenis (signed
,unsigned
, danchar
) lebih halus daripada pertama kali muncul. Nilai dalam kisaran 0 hinggaSCHAR_MAX
(yaitu 127 untuk 8-bitchar
) mudah:Tetapi, ketika
somevalue
berada di luar rentang itu, hanya melaluiunsigned char
memberi Anda hasil yang konsisten untuk nilai-nilai "sama"char
di ketiga jenis:Ini penting ketika menggunakan fungsi dari ctype.h , seperti
isupper
atautoupper
, karena ekstensi tanda:Perhatikan bahwa konversi melalui int adalah implisit; ini memiliki UB yang sama:
Untuk memperbaiki ini, masuk melalui
unsigned char
, yang mudah dilakukan dengan pembungkus ctype.h fungsi melalui safe_ctype :Ini berfungsi karena setiap fungsi yang mengambil salah satu dari ketiga tipe char juga dapat mengambil dua tipe char lainnya. Ini mengarah ke dua fungsi yang dapat menangani salah satu jenis:
ord(c)
selalu memberi Anda nilai non-negatif - bahkan ketika melewati negatifchar
atau negatifsigned char
- danchr
mengambil nilai apa punord
menghasilkan dan memberikan kembali yang sama persischar
.Dalam prakteknya, saya mungkin hanya akan melemparkan
unsigned char
alih-alih menggunakan ini, tetapi mereka membungkus gips secara ringkas, menyediakan tempat yang nyaman untuk menambahkan pengecekan kesalahan untukint
-to-char
, dan akan lebih pendek dan lebih jelas ketika Anda perlu menggunakannya beberapa kali dalam jarak dekat.sumber
Gunakan
static_cast<int>
:Sunting: Anda mungkin harus mencoba menghindari penggunaan
(int)
lihat mengapa menggunakan static_cast <int> (x) bukan (int) x? untuk info lebih lanjut.
sumber
Itu semacam tergantung pada apa yang Anda maksud dengan "mengkonversi".
Jika Anda memiliki serangkaian karakter yang mewakili integer, seperti "123456", maka ada dua cara khas untuk melakukannya di C: Gunakan konversi tujuan khusus seperti atoi () atau strtol () , atau sscanf tujuan umum () . C ++ (yang benar-benar bahasa yang berbeda menyamar sebagai peningkatan) menambahkan stringstreams ketiga.
Jika Anda ingin pola bit yang tepat di salah satu
int
variabel Anda diperlakukan sebagaichar
, itu lebih mudah. Dalam C tipe integer yang berbeda benar-benar lebih merupakan keadaan pikiran daripada "tipe" yang terpisah. Hanya mulai menggunakannyachar
di mana diminta, dan Anda harus baik-baik saja. Anda mungkin perlu konversi eksplisit untuk membuat kompilator berhenti merengek pada kesempatan, tetapi semua yang harus dilakukan adalah menjatuhkan bit tambahan melewati 256.sumber
Saya benar-benar memiliki
null
keterampilan dalam C, tetapi untuk penguraian sederhana:... ini bekerja untuk saya:
sumber
Mungkin Anda menginginkan konversi ini untuk menggunakan fungsi-fungsi dari pustaka standar C.
Dalam hal ini, lakukan (sintaks C ++)
Ekspresi
UChar( c )
dikonversi keunsigned char
untuk menghilangkan nilai-nilai negatif, yang, kecuali untuk EOF, tidak didukung oleh fungsi C.Kemudian hasil dari ungkapan itu digunakan sebagai argumen aktual untuk
int
argumen formal. Di mana Anda mendapatkan promosi otomatisint
. Anda dapat juga menulis langkah terakhir secara eksplisit, sepertiint( UChar( c ) )
, tetapi secara pribadi saya menemukan itu terlalu bertele-tele.Ceria & hth.,
sumber
Saya mengalami masalah dalam mengubah array char seperti
"7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"
menjadi nilai integer aktual yang akan dapat diwakili oleh `7C 'sebagai satu nilai heksadesimal. Jadi, setelah mencari bantuan, saya membuat ini, dan berpikir itu akan keren untuk dibagikan.Ini memisahkan string char menjadi bilangan bulat kanannya, dan mungkin bermanfaat bagi lebih banyak orang daripada hanya saya;)
Semoga ini bisa membantu!
sumber
Untuk karakter atau pendek ke int, Anda hanya perlu menetapkan nilainya.
Sama dengan int64.
Semua nilai akan menjadi 16.
sumber
Anda dapat menggunakan metode atoi ini untuk mengonversi char ke int. Untuk informasi lebih lanjut, Anda dapat merujuk ke http://www.cplusplus.com/reference/cstdlib/atoi/ ini , http://www.cplusplus.com/reference/string/stoi/ .
sumber