Konversi char ke int di C dan C ++


401

Bagaimana cara mengonversi a charke intdalam C dan C ++?


1
@ 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 .


14
ia = (a - '0')% 48;
Kshitij Banerjee

@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:

int x = (int)character - 48;

19
@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.

char c = 'a'; // narrowing on C
int a = c;

3
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;
signed char sc = c;
unsigned char 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;
signed char sc = c;
unsigned char uc = c;
// Might not be true: int(c) == int(sc) and int(c) == int(uc).
int nc = (unsigned char)c;
int nsc = (unsigned char)sc;
int nuc = (unsigned char)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(unsigned char 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 (unsigned char)c; }
char chr(int n) {
  assert(0 <= n);  // Or other error-/sanity-checking.
  assert(n <= UCHAR_MAX);
  return (unsigned char)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.



7

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.


6

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 ++)

typedef unsigned char UChar;

char myCppFunc( char c )
{
    return char( 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.

Ceria & hth.,


0

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;)

unsigned int* char2int(char *a, int len)
{
    int i,u;
    unsigned int *val = malloc(len*sizeof(unsigned long));

    for(i=0,u=0;i<len;i++){
        if(i%2==0){
            if(a[i] <= 57)
                val[u] = (a[i]-50)<<4;
            else
                val[u] = (a[i]-55)<<4;
        }
        else{
            if(a[i] <= 57)
                val[u] += (a[i]-50);
            else
                val[u] += (a[i]-55);
            u++;
        }
    }
    return val;
}

Semoga ini bisa membantu!


Pernahkah Anda menguji kode ini? 50 harus berupa 48, 55 hanya berfungsi untuk huruf ASCII huruf besar sementara contoh Anda berisi huruf kecil.
Roland Illig

0

Untuk karakter atau pendek ke int, Anda hanya perlu menetapkan nilainya.

char ch = 16;
int in = ch;

Sama dengan int64.

long long lo = ch;

Semua nilai akan menjadi 16.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.