Ubah digit karakter menjadi bilangan bulat yang sesuai di C

103

Apakah ada cara untuk mengubah karakter menjadi integer di C?

Misalnya, dari '5'ke 5?

Mengalir
sumber

Jawaban:

149

Sesuai balasan lainnya, ini bagus:

char c = '5';
int x = c - '0';

Selain itu, untuk pemeriksaan kesalahan, Anda mungkin ingin memeriksa apakah isdigit (c) benar terlebih dahulu. Perhatikan bahwa Anda tidak dapat melakukan hal yang sama secara portabel untuk surat, misalnya:

char c = 'b';
int x = c - 'a'; // x is now not necessarily 1

Standar menjamin bahwa nilai karakter untuk angka '0' hingga '9' berdekatan, tetapi tidak menjamin untuk karakter lain seperti huruf alfabet.

Chris Young
sumber
3
@Paul Tomblin: Ya untuk angka, bukan huruf, karena, seperti yang saya katakan di jawaban, jaminan standar '0' hingga '9' bersebelahan tetapi tidak memberikan jaminan untuk karakter lain seperti 'a' hingga 'z'.
Chris Young
char c = 'b'; int x = c - 'a'; lalu x akan menjadi 1 hanya di ASCII?
Pan
@Pan Dalam pengkodean apa pun, termasuk ASCII, yang memiliki 'b' 1 lebih banyak daripada 'a'. Ini masih berlaku di EBCDIC, namun itu membuat ('j' - 'i') == 8.
Chris Young
@Mengapa? Penyebab EBCDIC, 'j' tidak 1 lebih dari 'i'?
Pan
2
Apa yang saya lewatkan di sini dimana atoi tidak digunakan?
Daniel
41

Kurangi '0' seperti ini:

int i = c - '0';

C Standard menjamin setiap digit di kisaran '0'..'9'adalah salah satu lebih besar dari angka sebelumnya (di bagian 5.2.1/3dari rancangan C99 ). Jumlah yang sama untuk C ++.

Johannes Schaub - litb
sumber
1
Jawaban ini akan lebih baik jika Anda menyebutkan bahwa char adalah / sudah / efektif adalah integer, albiet implementasi yang ditentukan tanda (misalnya, mungkin ditandatangani atau tidak ditandatangani), dan panjang CHAR_BITS.
Arafangion
saya tidak yakin mengetahui itu benar-benar membantunya. tapi Chris membuat poin yang bagus dengan a..z tidak perlu bersebelahan. saya seharusnya menyebutkan itu sebagai gantinya. sekarang dia memenangkan perlombaan :)
Johannes Schaub - litb
1
Jawaban Anda lebih baik karena Anda telah memenuhi syarat untuk jawaban Anda - Chris mungkin saja mengarang barangnya. :)
Arafangion
terima kasih atas apresiasinya. saya akui saya tidak yakin tentang status C. jadi saya melihat ke atas dan karena saya sudah melakukannya, saya menempelkan referensi ke jawabannya :)
Johannes Schaub - litb
Dan itu, Pak, itulah mengapa Anda mendapat beberapa poin lebih banyak daripada saya. :)
Arafangion
29

Jika, secara kebetulan, Anda ingin mengonversi serangkaian karakter menjadi bilangan bulat, Anda juga dapat melakukannya!

char *num = "1024";
int val = atoi(num); // atoi = ASCII TO Int

valsekarang 1024. Tampaknya atoi()baik-baik saja, dan apa yang saya katakan sebelumnya hanya berlaku untuk saya (di OS X (mungkin (masukkan lelucon Lisp di sini))). Saya pernah mendengar itu adalah makro yang memetakan secara kasar ke contoh berikutnya, yang menggunakan strtol(), fungsi yang lebih umum, untuk melakukan konversi sebagai gantinya:

char *num = "1024";
int val = (int)strtol(num, (char **)NULL, 10); // strtol = STRing TO Long

strtol() bekerja seperti ini:

long strtol(const char *str, char **endptr, int base);

Ini diubah *strmenjadi long, memperlakukannya seolah-olah itu adalah basebilangan dasar . Jika **endptrbukan nol, ia memegang karakter non-digit pertama yang strtol()ditemukan (tapi siapa yang peduli tentang itu).

Chris Lutz
sumber
Tidak ada masalah utas dengan atoi (tidak ada data statis) dan tidak usang. Bahkan secara fungsional setara dengan: #define atoi (x) (int) (strtol ((x), NULL, 10)
Evan Teran
5
Masalah dengan atoi adalah bahwa ia menggunakan 0 sebagai nilai "tidak dapat menemukan nomor di sini", jadi atoi ("0") dan atoi ("satu") keduanya mengembalikan 0. Jika itu tidak berhasil untuk apa yang Anda ' kembali menggunakannya untuk, cari strtol () atau sscanf ().
David Thornley
Keuntungan lain dari strtol, tentu saja, adalah Anda mungkin perlu membaca hal-hal lain dari string yang sama yang muncul setelah nomor tersebut.
dfeuer
@EvanTeran Sayangnya jika Anda menjalankan Visual Studio Anda mendapatkan peringatan depresiasi (dan tidak akan mengkompilasi tanpa dinonaktifkan). VS sekarang merekomendasikan itoa_s().
Simon
7

Kurangi char '0' atau int 48 seperti ini:

char c = '5';
int i = c - '0';

Penjelasan: Secara internal berfungsi dengan nilai ASCII . Dari tabel ASCII, nilai desimal karakter 5 adalah 53 dan 0 adalah 48 . Jadi 53 - 48 = 5

ATAU

char c = '5';
int i = c - 48; // Because decimal value of char '0' is 48

Itu berarti jika Anda mengurangi 48 dari karakter angka mana pun, itu akan mengubah bilangan bulat secara otomatis.

Arif
sumber
6
char numeralChar = '4';
int numeral = (int) (numeralChar - '0');
Kevin Conner
sumber
numeralChar - '0'sudah bertipe int, jadi Anda tidak perlu pemerannya. Bahkan jika tidak, pemerannya tidak diperlukan.
Alok Singhal
Huh, ya itu akan memaksa, bukan? Mungkin Jawa mewarnai persepsiku. Atau mungkin saya salah sepenuhnya dan bahkan akan memaksa di Jawa. :)
Kevin Conner
5

Untuk mengubah digit karakter menjadi bilangan bulat yang sesuai. Lakukan seperti yang ditunjukkan di bawah ini:

char c = '8';                    
int i = c - '0';

Logika di balik kalkulasi di atas adalah bermain-main dengan nilai ASCII. Nilai ASCII karakter 8 adalah 56, nilai ASCII karakter 0 adalah 48. Nilai ASCII dari integer 8 adalah 8.

Jika kita mengurangi dua karakter, pengurangan akan terjadi antara karakter ASCII.

int i = 56 - 48;   
i = 8;
Ashish
sumber
Mengapa saya satu-satunya yang memberi suara positif? Penjelasannya sangat sederhana dan informatif: +1:
Brandon Benefield
0

Jika hanya satu karakter 0-9 dalam ASCII, maka mengurangi nilai karakter nol ASCII dari nilai ASCII seharusnya berfungsi dengan baik.

Jika Anda ingin mengonversi angka yang lebih besar maka hal berikut akan dilakukan:

char *string = "24";

int value;

int assigned = sscanf(string, "%d", &value);

** jangan lupa untuk memeriksa status (yang seharusnya 1 jika berhasil dalam kasus di atas).

Paul.

Paul W Homer
sumber
0
char chVal = '5';
char chIndex;

if ((chVal >= '0') && (chVal <= '9')) {

    chIndex = chVal - '0';
}
else 
if ((chVal >= 'a') && (chVal <= 'z')) {

    chIndex = chVal - 'a';
}
else 
if ((chVal >= 'A') && (chVal <= 'Z')) {

    chIndex = chVal - 'A';
}
else {
    chIndex = -1; // Error value !!!
}
Alphaneo
sumber
0

Ketika saya perlu melakukan sesuatu seperti ini, saya membuat array dengan nilai yang saya inginkan.

const static int lookup[256] = { -1, ..., 0,1,2,3,4,5,6,7,8,9, .... };

Maka konversinya mudah

int digit_to_int( unsigned char c ) { return lookup[ static_cast<int>(c) ]; }

Ini pada dasarnya adalah pendekatan yang diambil oleh banyak implementasi pustaka ctype. Anda dapat dengan mudah mengadaptasi ini untuk bekerja dengan digit hex juga.

Michael Anderson
sumber
Itu tampaknya sangat tidak efisien untuk mengonversi satu digit desimal (atau oktal). Jika bagian yang relevan dari tabel pencarian Anda tidak berada dalam cache L1, Anda akan meledakkan banyak siklus untuk menariknya hanya untuk mendapatkan satu nilai. Terus terang, saya cenderung meragukan ini bahkan ide yang bagus jika Anda mengonversi banyak digit, tetapi Anda harus mengukurnya. Ini jauh lebih kompetitif untuk hex, tentunya.
dfeuer
0

Periksa ini,

char s='A';

int i = (s<='9')?(s-'0'):(s<='F')?((s-'A')+10):((s-'a')+10);

hanya 0,1,2, ...., E, F.

Siwa
sumber
0

Cukup gunakan atol()fungsinya:

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    const char *c = "5";
    int d = atol(c);
    printf("%d\n", d);

}
Aula Dylan
sumber
0

Jika digit Anda, katakanlah, '5'dalam ASCII ini direpresentasikan sebagai bilangan biner 0011 0101(53). Setiap digit memiliki empat bit tertinggi 0011dan 4 bit terendah mewakili digit dalam bcd. Jadi, lakukan saja

char cdig = '5';
int dig = cdig & 0xf; // dig contains the number 5

untuk mendapatkan 4 bit terendah, atau, yang sama, digitnya. Dalam asm, ia menggunakan andoperasi alih-alih sub(seperti dalam jawaban lain).

Garmekain
sumber
'5'adalah 53 ( 00110101)
eyllanesc
@eyllanesc Awalnya 4. Terima kasih. Diedit.
Garmekain
0

Berikut adalah fungsi pembantu yang memungkinkan untuk mengubah digit dalam char menjadi int dan sebaliknya:

int toInt(char c) {
    return c - '0';
}

char toChar(int i) {
    return i + '0';
}
Maxim Makhun
sumber
-2

gunakan fungsi: atoi untuk array ke integer, atof untuk array ke tipe float; atau

char c = '5';
int b = c - 48;
printf("%d", b);
K.tin
sumber
Beberapa jawaban sudah mencakup ini. Ini tidak menambahkan apa pun yang belum mereka tutupi.
ShadowRanger
-3

Anda akan melemparkannya ke int (atau float atau double atau apa pun yang ingin Anda lakukan dengannya) dan menyimpannya dalam variabel anoter.

SeanJA
sumber