วิธีแปลง char เป็น int


124

เป็นวิธีที่เหมาะสมในการแปลงอะไรcharไปint? สิ่งนี้ให้49:

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

ฉันไม่ต้องการแปลงเป็นสตริงแล้วแยกวิเคราะห์


1
คำถามนี้อาจซ้ำกันได้
RBT

อาจซ้ำกันของการแปลงถ่านเป็น int ใน C #
GSerg

คำตอบ:


283

ฉันแปลกใจที่ไม่มีใครพูดถึงวิธีการคงที่ที่สร้างขึ้นในSystem.Char...

int val = (int)Char.GetNumericValue('8');
// val == 8

18
จุดดี! +1 แปลกมากที่ส่งกลับ a doubleแม้ว่า
Marc Gravell

4
ฉันเห็นด้วยฉันคิดไม่ออกว่าทำไมมันถึงส่งกลับ 'double' - อักขระตัวเดียวจะเป็นตัวแทนของตัวเลขทศนิยมได้อย่างไร
Joel Mueller

49
มีอักขระ Unicode จำนวนมากที่เป็นตัวแทนของจำนวนที่ไม่ใช่จำนวนเต็มเช่นมีU + 2153
dtb

26
@dtb - ฉันไม่ได้พิจารณาอย่างนั้น กลับไม่แน่นอนChar.GetNumericValue('⅓') 0.3333...ขอบคุณที่ชี้ให้ดู!
Joel Mueller

1
Foot Note: ขณะนี้ฟังก์ชันนี้ไม่สามารถใช้ได้ใน NetMF
GisMofx

40

แล้ว (สำหรับchar c)

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

การย่อยของค่าถ่านคืออะไร

คำถามเกี่ยวกับ API (ความคิดเห็น) อาจเป็นวิธีการขยายหรือไม่

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

จากนั้นใช้ int x = c.ParseInt32();


1
ฉันควรจะพูดถึงฉันรู้เกี่ยวกับเรื่องนี้ แต่มีวิธีอื่นหรือไม่? ฉันอยากรู้ว่ามี API สำหรับทำสิ่งนี้หรือไม่?
tvr

4
หากคุณต้องการให้มีลักษณะคล้ายกับ bahavior int.Parseกล่าวคือมีข้อยกเว้นเกิดขึ้นกับอินพุตที่ไม่ถูกต้องคุณจะต้องเพิ่มการตรวจสอบขอบเขตเพิ่มเติม:if (i < 0 || i > 9) throw new FormatException();
Dirk Vollmar

@ user386338 กลัวว่าจะไม่มี
Eugene Cheverda

@ user386338 - การปรับปรุงด้วยใหม่ API ตัวเลือกยังรวมถึงข้อเสนอแนะ @ 0xA3 ของ
มาร์ค Gravell

@ user386338 - ดูคำตอบของ Joel สำหรับวิธี inbuilt API
Marc Gravell

21

สิ่งที่ทุกคนลืมคือการอธิบายว่าทำไมสิ่งนี้จึงเกิดขึ้น

Char เป็นจำนวนเต็ม แต่มีตัวชี้ในตาราง ASCII อักขระทั้งหมดมีค่าจำนวนเต็มที่สอดคล้องกันดังที่คุณเห็นได้ชัดเจนเมื่อพยายามแยกวิเคราะห์

Pranay มีชุดอักขระที่แตกต่างกันอย่างชัดเจนนั่นคือสาเหตุที่รหัส HIS ใช้ไม่ได้ วิธีเดียวคือ

int val = '1' - '0';

เนื่องจากสิ่งนี้ค้นหาค่าจำนวนเต็มในตาราง'0'ซึ่งเป็น 'ค่าฐาน' ที่ลบตัวเลขของคุณในรูปแบบถ่านจากสิ่งนี้จะทำให้คุณได้ตัวเลขเดิม


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

อีกทางเลือกหนึ่ง:

int i = c & 0x0f;

สิ่งนี้ควรทำให้สำเร็จเช่นกัน


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

สามารถทำได้โดยใช้รหัส ascii โดยที่ '0' เป็นค่าต่ำสุดและอักขระตัวเลขจะนับขึ้นจากที่นั่น


ยอดเยี่ยมมาก! imo เป็นโซลูชันที่หรูหราที่สุดที่นี่
arabisoft

3
int val = '1' - 48;

@Luke Xu: '0' มีรหัส ASCII 0x30 ซึ่งเป็น 48 ในฐานสิบดังนั้นนี่จึงเหมือนกับ '1' - '0'
NiKiZe

3

คุณสามารถใช้วิธีการขยายต่อไปนี้:

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';
        }
    }

1
@ 0xA3 การตรวจสอบช่วงจะต้องอยู่ที่จุดเริ่มต้นของวิธีการโดยทั่วไป ความหมายถ้าหากเราจะแปลงcharไปintเราจะต้องตรวจสอบช่วงของพารามิเตอร์ที่ไม่ได้ผลผลิตintคุ้มค่า
Eugene Cheverda

ไม่จำเป็นต้องตรวจสอบintค่าผลลัพธ์เนื่องจากช่วงของอักขระตัวเลขถูกดำเนินการในช่วงเริ่มต้นของวิธีการดังนั้นจะมีค่าผลลัพธ์ที่ถูกต้องหาก char ที่ระบุไม่อยู่ในช่วงของอักขระตัวเลขจะมีข้อยกเว้น ตรรกะเดียวกันกับที่คุณระบุ แต่การตรวจสอบช่วงจะดำเนินการที่จุดเริ่มต้นของวิธีการ
Eugene Cheverda

ขออภัยฉันอ่านตัวอย่างโค้ดของคุณผิด บางครั้งก็ยากที่จะเห็นสิ่งที่ชัดเจนที่สุด ฉันพนันได้เลยว่ารหัสดังกล่าวif (c < 0 || c > 9)...
Dirk Vollmar

1

วิธีที่ปลอดภัยที่สุดในการทำสิ่งนี้คือการใช้เมธอด Int32.TryParse ดูที่นี่: http://dotnetperls.com/int-tryparse


TryParse ใช้สำหรับสตริงที่ไม่ใช่สำหรับตัวอักษร
tvr

ใช่ แต่ยังคงเป็นวิธีที่ปลอดภัยที่สุดในการทำให้เกิด Conversion
MUG4N

1
การแปลงอักขระเดี่ยวเป็นจำนวนเต็มถือเป็นเรื่องความปลอดภัยหรือไม่?
Joel Mueller

1
'ปลอดภัย' ในกรณีนี้หมายความว่าจะไม่ทำให้เกิดปัญหาหากถ่านของคุณไม่ใช่หมายเลข ascii จริงอาจเป็นอักขระยูนิโคดแบบหลายไบต์
Robin Bennett

1
int val = '1' & 15;

ไบนารีของอักขระ ASCII 0-9 คือ:

0 - 00110000

1 - 00110001

2 - 00110010

3 - 00110011

4 - 00110100

5 - 00110101

6 - 00110110

7 - 00110111

8 - 00111000

9 - 00111001

และถ้าคุณใช้ LSB 4 ตัวแรกในแต่ละตัว (โดยใช้ bitwise และด้วย 8'b00001111 ที่เท่ากับ 15) คุณจะได้จำนวนจริง (0000 = 0,0001 = 1,0010 = 2, ... )


สิ่งนี้ทำงานอย่างไรในแง่ของประเภท? คุณกำลังใช้ตัวดำเนินการแบบบิตระหว่าง char และ int แล้วส่งกลับ int? ตรรกะ AND ใช้การแทนค่าไบนารีของทั้ง char และ int และส่งกลับการแทนค่าไบนารีจากนั้นเมื่อคุณกำหนด var เป็น int จะใช้การแทนค่านั้นหรือไม่
mitomed

@mitnomed ใช่และถ้าคุณใช้ไบต์เช่นมันจะใช้การแทนค่าไบต์
Tomer Wolberg

0

คุณสามารถลองสิ่งนี้:

int val = Convert.ToInt32("" + '1');

ทำไมไม่แค่. ToString ()?
Veikedo

@ Veikedo เขาต้องการ int ไม่ใช่สตริง
briba

6
ฉันหมายถึงConvert.ToInt32('1'.ToString())
Veikedo

0

ส่วนขยายของคำตอบอื่น ๆ ที่ครอบคลุมการแสดงเลขฐานสิบหก:

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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.