แปลงตัวเลขของอักขระเป็นจำนวนเต็มที่สอดคล้องกันใน C


103

มีวิธีแปลงอักขระเป็นจำนวนเต็มใน C หรือไม่?

ตัวอย่างเช่นจาก'5'ถึง 5?

คำตอบ:


152

ตามคำตอบอื่น ๆ สิ่งนี้ใช้ได้:

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

นอกจากนี้สำหรับการตรวจสอบข้อผิดพลาดคุณอาจต้องการตรวจสอบ isdigit (c) เป็นจริงก่อน โปรดทราบว่าคุณไม่สามารถเคลื่อนย้ายได้อย่างสมบูรณ์สำหรับตัวอักษรตัวอย่างเช่น:

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

มาตรฐานรับประกันว่าค่าถ่านสำหรับตัวเลข '0' ถึง '9' นั้นติดกัน แต่ไม่รับประกันสำหรับอักขระอื่น ๆ เช่นตัวอักษรของตัวอักษร


3
@ Paul Tomblin: ใช่สำหรับตัวเลขไม่ใช่ตัวอักษรเพราะตามที่ฉันได้กล่าวไว้ในคำตอบมาตรฐานการรับประกัน '0' ถึง '9' นั้นติดกัน แต่ไม่ได้รับประกันเช่นนั้นสำหรับอักขระอื่น ๆ เช่น 'a' ถึง 'z'
Chris Young

ถ่าน c = 'b'; int x = c - 'ก'; แล้ว x จะเป็น 1 เฉพาะใน ASCII?
ปาน

@Pan ในการเข้ารหัสใด ๆ รวมถึง ASCII ที่มี 'b' 1 มากกว่า 'a' สิ่งนี้ยังคงเป็นจริงใน EBCDIC อย่างไรก็ตามมันทำให้ ('j' - 'i') == 8.
Chris Young

@ChrisYoung ทำไม? สาเหตุใน EBCDIC 'j' ไม่เกิน 1 มากกว่า 'i'?
ปาน

2
ฉันพลาดอะไรไปที่ที่ไม่ได้ใช้ atoi?
Daniel

41

ลบ '0' ดังนี้:

int i = c - '0';

มาตรฐาน C รับประกันว่าแต่ละหลักในช่วง'0'..'9'นั้นมากกว่าตัวเลขก่อนหน้า (ในส่วน5.2.1/3ของร่าง C99 ) C ++ ก็เช่นเดียวกัน


1
คำตอบนี้จะดีกว่าถ้าคุณกล่าวว่า char เป็น / อยู่แล้ว / มีประสิทธิภาพเป็นจำนวนเต็ม, อัลเบตของเครื่องหมายที่กำหนดการนำไปใช้งาน (เช่นอาจลงนามหรือไม่ได้ลงนาม) และยาว CHAR_BITS
Arafangion

ฉันไม่แน่ใจว่ารู้ว่าช่วยเขาได้จริงๆ แต่คริสสร้างจุดที่ดีโดยที่ a..z ไม่ได้อยู่ติดกัน ฉันควรจะพูดถึงเรื่องนี้แทน ตอนนี้เขาชนะการแข่งขัน :)
Johannes Schaub - litb

1
ของคุณดีกว่าเพราะคุณผ่านการรับรองคำตอบของคุณ - คริสสามารถสร้างสิ่งของของเขาได้เป็นอย่างดี :)
Arafangion

ขอบคุณสำหรับความชื่นชม ฉันยอมรับว่าฉันไม่แน่ใจเกี่ยวกับสถานะของ C. ดังนั้นฉันจึงมองขึ้นไปและ 'เพราะฉันอยู่ที่นั่นแล้วฉันวางการอ้างอิงลงในคำตอบ :)
Johannes Schaub - litb

และนั่นคือสาเหตุที่คุณมีคะแนนมากกว่าฉันสองสามคะแนน :)
Arafangion

30

ถ้าบังเอิญคุณต้องการแปลงสตริงอักขระเป็นจำนวนเต็มคุณก็ทำได้เช่นกัน!

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

valตอนนี้คือ 1024 เห็นได้ชัดว่าปกติatoi()ดีและสิ่งที่ฉันพูดเกี่ยวกับเรื่องนี้ก่อนหน้านี้ใช้ได้กับฉันเท่านั้น (บน OS X (อาจจะ (แทรกเรื่องตลก Lisp ที่นี่))) ฉันเคยได้ยินมาว่ามันเป็นมาโครที่แมปคร่าวๆกับตัวอย่างถัดไปซึ่งใช้strtol()ฟังก์ชันที่มีวัตถุประสงค์ทั่วไปมากขึ้นเพื่อทำการแปลงแทน:

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

strtol() ทำงานเช่นนี้:

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

มันแปลง*strเป็น a longโดยถือว่ามันเป็นbaseเลขฐาน หาก**endptrไม่เป็นโมฆะจะมีอักขระที่ไม่ใช่ตัวเลขตัวแรกที่strtol()พบ (แต่ใครจะสนใจ)


ไม่มีปัญหาเธรดกับ atoi (ไม่มีข้อมูลคงที่) และไม่ได้เลิกใช้งาน ในความเป็นจริงมันเทียบเท่ากับ: #define atoi (x) (int) (strtol ((x), NULL, 10)
Evan Teran

5
ปัญหาของ atoi คือมันใช้ 0 เป็นค่า "ไม่พบตัวเลขที่นี่" ดังนั้น atoi ("0") และ atoi ("one") ทั้งคู่จะคืนค่าเป็น 0 หากไม่ได้ผลกับสิ่งที่คุณ กำลังใช้งานอยู่ให้มองหา strtol () หรือ sscanf ()
David Thornley

ข้อดีอีกอย่างของ strtol ก็คือคุณอาจต้องอ่านสิ่งอื่น ๆ จากสตริงเดียวกันที่มาหลังตัวเลข
dfeuer

@EvanTeran น่าเสียดายถ้าคุณเรียกใช้ Visual Studio คุณจะได้รับคำเตือนเรื่องค่าเสื่อมราคา (และไม่สามารถคอมไพล์ได้โดยไม่ถูกปิดใช้งาน) VS แนะนำitoa_s()เลย
Simon

7

เพื่อแปลงตัวเลขของอักขระเป็นจำนวนเต็มที่สอดคล้องกัน ทำตามที่แสดงด้านล่าง:

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

ตรรกะเบื้องหลังการคำนวณข้างต้นคือการเล่นกับค่า ASCII ค่า ASCII ของอักขระ 8 คือ 56 ค่า ASCII ของอักขระ 0 คือ 48 ค่า ASCII ของจำนวนเต็ม 8 คือ 8

หากเราลบอักขระสองตัวการลบจะเกิดขึ้นระหว่าง ASCII ของอักขระ

int i = 56 - 48;   
i = 8;

ทำไมฉันถึงเป็นคนเดียวที่โหวตให้คะแนนนี้ คำอธิบายนั้นง่ายและให้ข้อมูลมาก: +1:
Brandon Benefield

7

ลบถ่าน '0' หรือ int 48 ดังนี้:

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

คำอธิบาย: ภายในใช้ได้กับ ค่าASCII จากตาราง ASCII ค่าทศนิยมของตัวละคร5 คือ 53และ0 48 ดังนั้น53-48 = 5

หรือ

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

นั่นหมายความว่าถ้าคุณหัก 48ออกจากอักขระตัวเลขใด ๆ ก็จะแปลงจำนวนเต็มโดยอัตโนมัติ


6
char numeralChar = '4';
int numeral = (int) (numeralChar - '0');

numeralChar - '0'เป็นประเภทอยู่แล้วintดังนั้นคุณไม่จำเป็นต้องมีนักแสดง แม้ว่าจะไม่ใช่ แต่ก็ไม่จำเป็นต้องใช้นักแสดง
Alok Singhal

หึใช่ว่าจะบีบบังคับใช่ไหม บางที Java อาจทำให้การรับรู้ของฉันเป็นสี หรือบางทีฉันอาจจะเข้าใจผิดไปหมดและมันจะบีบบังคับใน Java :)
Kevin Conner

0

หากเป็นเพียงอักขระ 0-9 ตัวเดียวใน ASCII การลบค่าของอักขระศูนย์ ASCII ออกจากค่า ASCII ก็น่าจะใช้ได้ดี

หากคุณต้องการแปลงตัวเลขที่มากขึ้นสิ่งต่อไปนี้จะทำ:

char *string = "24";

int value;

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

** อย่าลืมตรวจสอบสถานะ (ซึ่งควรเป็น 1 หากใช้งานได้ในกรณีข้างต้น)

พอล.


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

0

เมื่อฉันต้องการทำสิ่งนี้ฉันจะสร้างอาร์เรย์ล่วงหน้าด้วยค่าที่ฉันต้องการ

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

จากนั้นการแปลงเป็นเรื่องง่าย

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

โดยพื้นฐานแล้วเป็นแนวทางที่นำมาใช้โดยการใช้งานไลบรารี ctype จำนวนมาก คุณสามารถปรับให้เข้ากับเลขฐานสิบหกได้เช่นกัน


ดูเหมือนจะไม่มีประสิทธิภาพอย่างยิ่งสำหรับการแปลงเลขฐานสิบเดียว (หรือฐานแปด) หากส่วนที่เกี่ยวข้องของตารางการค้นหาของคุณไม่ได้อยู่ในแคช L1 คุณจะต้องระเบิดหลายรอบเพื่อดึงมันเข้ามาเพื่อให้ได้ค่าเดียว ตรงไปตรงมาฉันมักจะสงสัยว่านี่เป็นความคิดที่ดีหากคุณกำลังแปลงจำนวนหลักทั้งหมด แต่คุณต้องวัดสิ่งนั้น แน่นอนว่ามันสามารถแข่งขันกับฐานสิบหกได้มากขึ้น
dfeuer



0

หากตัวเลขของคุณคือสมมติว่า'5'ใน ASCII จะแสดงเป็นเลขฐานสอง0011 0101(53) ทุกหลักมีสี่บิตสูงสุด0011และ 4 บิตต่ำสุดแทนตัวเลขใน bcd คุณก็แค่ทำ

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

เพื่อให้ได้ 4 บิตต่ำสุดหรือตัวเลขเท่ากัน ใน asm จะใช้andการดำเนินการแทนsub(เช่นเดียวกับคำตอบอื่น ๆ )


'5'คือ 53 ( 00110101)
eyllanesc

@eyllanesc ตอนแรกมันเป็น 4 ขอบคุณ แก้ไขแล้ว
Garmekain

0

นี่คือฟังก์ชั่นตัวช่วยที่อนุญาตให้แปลงตัวเลขใน char เป็น int และในทางกลับกัน:

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

char toChar(int i) {
    return i + '0';
}

-2

ใช้ฟังก์ชัน: atoi สำหรับอาร์เรย์เป็นจำนวนเต็ม, atof สำหรับอาร์เรย์เป็นประเภทลอย; หรือ

char c = '5';
int b = c - 48;
printf("%d", b);

คำตอบหลายคำตอบครอบคลุมเรื่องนี้แล้ว สิ่งนี้เพิ่มสิ่งที่พวกเขาไม่ได้ครอบคลุมอยู่แล้ว
ShadowRanger

-3

คุณจะส่งเป็น int (หรือ float หรือ double หรืออะไรก็ได้ที่คุณต้องการทำ) และเก็บไว้ในตัวแปร anoter

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