Bagaimana cara mengubah char menjadi int?

124

Apa cara yang tepat untuk mengkonversi charke int? Ini memberi 49:

int val = Convert.ToInt32('1');
//int val = Int32.Parse("1"); // Works

Saya tidak ingin mengubahnya menjadi string dan kemudian menguraikannya.

tvr
sumber
1
Kemungkinan duplikat dari pertanyaan ini .
NSP
Kemungkinan duplikat dari Convert char to int di C #
GSerg

Jawaban:

283

Saya terkejut tidak ada yang menyebutkan metode statis yang dibangun langsung ke System.Char...

int val = (int)Char.GetNumericValue('8');
// val == 8
Joel Mueller
sumber
18
Tempat yang bagus! +1 Sangat aneh bahwa ia mengembalikan a double, meskipun
Marc Gravell
4
Saya setuju, saya tidak tahu mengapa ia mengembalikan 'ganda' - bagaimana mungkin satu karakter mewakili bilangan floating-point?
Joel Mueller
49
Ada banyak karakter Unicode yang mewakili bilangan non-integer, misalnya, U + 2153 .
dtb
26
@dtb - Saya tidak mempertimbangkan itu. Char.GetNumericValue('⅓')memang kembali 0.3333.... Terima kasih telah menunjukkannya!
Joel Mueller
1
Catatan Kaki: fungsi ini saat ini tidak tersedia di NetMF.
GisMofx
40

bagaimana dengan (untuk char c)

int i = (int)(c - '0');

yang melakukan substraksi dari nilai char?

Apakah pertanyaan API (komentar), mungkin metode ekstensi?

public static class CharExtensions {
    public static int ParseInt32(this char value) {
        int i = (int)(value - '0');
        if (i < 0 || i > 9) throw new ArgumentOutOfRangeException("value");
        return i;
    }
}

lalu gunakan int x = c.ParseInt32();

Marc Gravell
sumber
1
Saya seharusnya menyebutkan, saya tahu tentang ini tetapi apakah ada cara lain? Saya ingin tahu apakah ada API untuk melakukan ini?
tvr
4
Jika Anda menginginkan bahavior serupa int.Parse, yaitu pengecualian dilemparkan pada input yang tidak valid Anda perlu menambahkan pemeriksaan batas tambahan:if (i < 0 || i > 9) throw new FormatException();
Dirk Vollmar
@ user386338 Saya khawatir tidak ada.
Eugene Cheverda
@ user386338 - diperbarui dengan sebuah opsi re API, juga termasuk @ umpan balik 0xA3 ini
Marc Gravell
@ user386338 - lihat jawaban Joel untuk metode API inbuilt
Marc Gravell
21

Apa yang semua orang lupakan adalah menjelaskan MENGAPA ini terjadi.

A Char, pada dasarnya adalah integer, tetapi dengan penunjuk di tabel ASCII. Semua karakter memiliki nilai integer yang sesuai seperti yang dapat Anda lihat dengan jelas saat mencoba menguraikannya.

Pranay jelas memiliki himpunan karakter yang berbeda, itulah sebabnya kodeNYA tidak berfungsi. satu-satunya cara adalah

int val = '1' - '0';

karena ini mencari nilai integer dalam tabel '0'yang kemudian merupakan 'nilai dasar' mengurangi bilangan Anda dalam format karakter dari ini akan memberi Anda bilangan asli.

Stefanvds
sumber
15
int i = (int)char.GetNumericValue(c);

Namun opsi lain:

int i = c & 0x0f;

Ini harus mencapai ini juga.

Grif
sumber
4
int val = '1' - '0';

Ini dapat dilakukan dengan menggunakan kode ascii dimana '0' adalah yang terendah dan jumlah karakter dihitung dari sana

Tristan
sumber
Ini luar biasa! Saya adalah solusi paling elegan di sini.
arabisoft
3
int val = '1' - 48;
x2.
sumber
@ Luke Xu: '0' memiliki kode ASCII 0x30 yang merupakan 48 dalam desimal jadi ini sama dengan '1' - '0'
NiKiZe
3

Anda dapat menggunakan metode ekstensi berikut:

public static class CharExtensions
    {
        public static int CharToInt(this char c)
        {
            if (c < '0' || c > '9')
                throw new ArgumentException("The character should be a number", "c");

            return c - '0';
        }
    }
Eugene Cheverda
sumber
1
@ 0xA3 Pemeriksaan jangkauan harus di awal metode secara umum. Secara semantik jika kita ingin mengkonversi charke intkita harus memeriksa rentang parameter input, bukan nilai output int.
Eugene Cheverda
Tidak perlu memeriksa intnilai hasil karena rentang karakter numerik dilakukan pada awal metode, sehingga akan ada nilai yang benar, jika karakter yang ditentukan tidak berada dalam rentang karakter numerik, pengecualian akan muncul. Logika yang sama seperti yang Anda berikan tetapi pemeriksaan rentang dilakukan di awal metode.
Eugene Cheverda
Maaf, saya salah membaca sampel kode Anda. Terkadang sulit untuk melihat hal yang paling jelas. Saya berani bertaruh bahwa kodenya mengatakan if (c < 0 || c > 9)...
Dirk Vollmar
1

Cara paling aman untuk melakukannya adalah menggunakan metode Int32.TryParse. Lihat di sini: http://dotnetperls.com/int-tryparse

MUG4N
sumber
TryParse adalah untuk string, bukan untuk karakter
tvr
Ya, itu hanyalah cara paling aman untuk mencapai konversi
MUG4N
1
Mengubah satu karakter menjadi integer adalah masalah keamanan?
Joel Mueller
1
'Aman' dalam hal ini berarti tidak akan menimbulkan masalah jika char Anda sebenarnya bukan nomor ascii - bisa jadi karakter unicode multi-byte.
Robin Bennett
1
int val = '1' & 15;

Biner dari karakter ASCII 0-9 adalah:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

dan jika Anda mengambil masing-masing 4 LSB pertama (menggunakan bitwise AND dengan 8'b00001111 yang setara dengan 15) Anda mendapatkan angka sebenarnya (0000 = 0,0001 = 1,0010 = 2, ...)

Tomer Wolberg
sumber
Bagaimana cara kerjanya dalam hal tipe? Anda menggunakan operator bitwise antara char dan int dan kemudian mengembalikan int? Apakah logika AND menggunakan representasi biner dari char dan int dan mengembalikan representasi biner dan ketika Anda mendefinisikan var sebagai int, ia menggunakan representasi itu?
dikurangi
@mitnomed yes dan jika Anda menggunakan byte misalnya maka itu menggunakan representasi byte.
Tomer Wolberg
0

Anda dapat mencoba sesuatu seperti ini:

int val = Convert.ToInt32("" + '1');
suap
sumber
mengapa tidak hanya .ToString ()?
Veikedo
@Veikedo dia ingin int, dan bukan string.
suap
6
Maksud sayaConvert.ToInt32('1'.ToString())
Veikedo
0

Perpanjangan dari beberapa jawaban lain yang mencakup representasi heksadesimal:

public int CharToInt(char c) 
{
    if (c >= '0' && c <= '9') 
    {
        return c - '0';
    }
    else if (c >= 'a' && c <= 'f') 
    {
        return 10 + c - 'a';
    }
    else if (c >= 'A' && c <= 'F') 
    {
        return 10 + c - 'A';
    }

    return -1;
}
Oleksandr Lytvyn
sumber