การแปลงสตรีมของ int เป็น char ใน java


114

สิ่งนี้อาจได้รับคำตอบที่อื่น แต่คุณจะได้รับค่าอักขระของค่า int ได้อย่างไร

โดยเฉพาะฉันกำลังอ่าน a จากสตรีม tcp และวิธีการอ่าน .read () ส่งกลับค่า int

ฉันจะได้รับถ่านจากสิ่งนี้ได้อย่างไร


1
คุณไม่ได้ระบุรายละเอียดเกี่ยวกับข้อมูลที่คุณกำลังส่งและอ่าน คุณส่งไบต์ไบนารีหรืออักขระ Unicode หรือไม่? วิธีการอ่าน .read () ส่งกลับค่า int ใช่ แต่จะส่งคืนอักขระที่อ่านแล้วเป็นจำนวนเต็มในช่วง 0 ถึง 65535 (หรือ -1 นี่เป็นเพราะฉันคิดว่า int ใช้แทน char) บางทีแค่ใช้public int read(char[] cbuf)จะแก้ปัญหาได้หรือไม่?
Vanuan

คำตอบสำหรับคำถามนี้ใช้ไม่ได้กับ JSP Java หากคุณใช้ jsp โปรดดูข้อผิดพลาดของสแต็กล้น: stackoverflow.com/questions/4621836/…
NuclearPeon

ฉันคิดว่านี่เป็นคำถามที่ถูกต้อง ความยากอย่างหนึ่งในการแปลงจำนวนเต็มเป็นถ่านคือการจัดการกับค่าลบและค่า> = 255
bvdb

จะเป็นอย่างไรถ้าฉันต้องการแปลงไบต์ที่อยู่ในอาร์เรย์ไบต์เป็นอักขระแล้วพิมพ์ลงในคอนโซล
Doug Hauf

คำตอบ:


74

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

เพียงแค่แคสต์จากintไปยังcharใช้งานได้ก็ต่อเมื่อคุณต้องการ ISO-8859-1 หากคุณกำลังอ่านไบต์จากสตรีมโดยตรง

แก้ไข: หากคุณกำลังแล้วใช้Readerแล้วหล่อค่าตอบแทนของread()ที่จะcharเป็นวิธีที่เหมาะสมที่จะไป (หลังจากการตรวจสอบไม่ว่าจะเป็น -1 หรือไม่) ... แต่ก็มีประสิทธิภาพมากขึ้นและสะดวกสบายโดยปกติจะเรียกread(char[], int, int)การอ่านบล็อกทั้งหมดของ ข้อความในแต่ละครั้ง อย่าลืมตรวจสอบค่าส่งคืนด้วยเพื่อดูจำนวนอักขระที่อ่านแล้ว


2
ฉันคิดว่านี่ไม่ใช่สิ่งที่ OP กำลังถามถึง เขาใช้วิธีการอ่านของผู้อ่าน: java.sun.com/j2se/1.4.2/docs/api/java/io/Reader.html#read ()คำถามที่เขาถามคือวิธีการแปลงค่าที่ส่งคืนโดยวิธีนี้เป็นถ่าน .
Vanuan

3
หากเขาใช้ Reader อย่างแท้จริงนั่นจะสร้างความแตกต่างได้อย่างแน่นอน มันไม่ชัดเจนเนื่องจากเขาพูดถึงสตรีมและผู้อ่าน (ด้วยตัวพิมพ์เล็ก r) ในประโยคเดียวกัน :( ได้แก้ไขคำตอบของฉันเพื่อให้ชัดเจน
Jon Skeet

คุณยังสามารถห่อInputStreamReaderใน a BufferedReaderดังที่กล่าวไว้ใน javadoc docs.oracle.com/javase/8/docs/api/java/io/…
bvdb

เหตุใด "เพียงแค่แคสต์จาก int เป็น char ก็ใช้ได้เฉพาะเมื่อคุณต้องการ ISO-8859-1 เท่านั้น" เป็นเพราะ Java ใช้ UTF-16 ภายในและอักขระ ISO-8859-1 ทั้งหมดเก็บหน่วยรหัส (บิต) เดียวกันใน UTF-16 หรือไม่
เซบาสเตียน

@ เซบาสเตียน: ใช่โดยพื้นฐานแล้ว
Jon Skeet

144

บางทีคุณอาจจะขอ:

Character.toChars(65) // returns ['A']

ข้อมูลเพิ่มเติม: Character.toChars(int codePoint)

แปลงอักขระที่ระบุ (จุดรหัส Unicode) เป็นการแสดง UTF-16 ที่เก็บไว้ในอาร์เรย์ถ่าน ถ้าจุดรหัสที่ระบุเป็นค่า BMP (Basic Multilingual Plane หรือ Plane 0) อาร์เรย์ถ่านที่ได้จะมีค่าเหมือนกับ codePoint หากจุดรหัสที่ระบุเป็นจุดรหัสเสริมอาร์เรย์ถ่านผลลัพธ์จะมีคู่ตัวแทนที่สอดคล้องกัน


9
จะใช้ได้ก็ต่อเมื่อจำนวนเต็มที่เป็นปัญหาเป็นจุดรหัส UTF-16 อยู่แล้ว เราไม่รู้ว่าเป็นเช่นนั้นหรือไม่
Jon Skeet

2
@ Atec: ไม่ประเด็นของฉันคือถ้าเขาแค่อ่านไบต์จากสตรีม (ไม่ชัดเจน) การแปลงโดยการแคสต์หรือการใช้toCharsมักจะไม่เหมาะสม ถ้าเขาอ่านจาก Reader ก็ไม่เป็นไร
Jon Skeet

2
ในขณะที่คำถามนี้ไม่ได้ระบุไว้เป็นที่ยอมรับคำถามนี้เกิดขึ้นเป็นผลลัพธ์แรกในการค้นหาโดย Google สำหรับการแปลงรหัส ASCII เป็นตัวอักษรดังนั้นฉันจึงโหวตให้
ArtOfWarfare

105

ขึ้นอยู่กับความหมายของคุณโดย "แปลง int เป็นถ่าน"

หากคุณต้องการเพียงแค่ร่ายค่าใน int คุณสามารถแคสต์โดยใช้รูปแบบการพิมพ์ของ Java

int i = 97; // 97 is 'a' in ASCII
char c = (char) i; // c is now 'a'

หากคุณหมายถึงการเปลี่ยนจำนวนเต็ม 1 ให้เป็นอักขระ '1' คุณสามารถทำได้ดังนี้:

if (i >= 0 && i <= 9) {
char c = Character.forDigit(i, 10);
....
}

จะเกิดอะไรขึ้นถ้าคุณเปลี่ยนจาก Char เป็น Integer? Integer.parseInt (c)?
พันธุ์

คำตอบนี้คือ :-)
voghDev

29

หากคุณต้องการเพียงแค่แปลง int 5 เป็นถ่าน '5': (สำหรับจำนวนเต็ม 0 - 9 เท่านั้น)

int i = 5;
char c = (char) ('0' + i); // c is now '5';

ไม่ใช่ .. '0' + 5 กลายเป็นสตริง '05' ด้านขวามือควรเป็น (ถ่าน) ((int) '0') + i;
Toddkaufmann

ไม่เป็นความจริงเนื่องจากอักขระไม่ได้รับการแปลงเป็น Strings ใน Java
Kaushik Shankar

+1 - ลองแล้วทดสอบได้ผล! ลองทดสอบด้วยตัวเองดูเหมือนว่าจะไม่เหมือนผู้แสดงความคิดเห็นที่นี่ ...
Ian Campbell

8

หล่อง่าย:

int a = 99;
char c = (char) a;

มีเหตุผลใดบ้างที่สิ่งนี้ไม่ได้ผลสำหรับคุณ?


1
คำแนะนำที่เป็นอันตรายหากสตรีมข้อความไม่ใช่ ASCII ที่บริสุทธิ์ ดูคำตอบของ Jon Skeet ด้านบน
sleske

1
มันอาจไม่ทำงาน แต่ฉันคิดว่ามันน่าจะจริง ชนิดข้อมูลถ่านเก็บค่ารหัส UTF-16 ดังนั้นในการร่ายถ่านเป็น int คุณต้องทำการเปลี่ยนแปลงบางอย่าง แต่เนื่องจาก OP ใช้เมธอด read () ซึ่งส่งคืนค่า UTF-16 coded value อย่างง่ายแล้วฉันจึงคิดว่า แก้ไขฉันถ้าฉันผิด
Vanuan

ขออภัยฉันหมายถึง "จาก int เป็นถ่าน"
Vanuan

สิ่งนี้จะทำให้เกิดค่าการเข้ารหัสที่ไม่คาดคิดไม่ใช่ตัวเลข
Vasil Valchev

4

โซลูชันนี้ใช้ได้กับขนาดความยาวจำนวนเต็ม = 1

Integer input = 9; Character.valueOf((char) input.toString().charAt(0))

ถ้าขนาด> 1 เราจำเป็นต้องใช้สำหรับการวนซ้ำและวนซ้ำ


1

คำตอบส่วนใหญ่ที่นี่เสนอทางลัดซึ่งอาจทำให้คุณประสบปัญหาใหญ่หากคุณไม่รู้ว่ากำลังทำอะไรอยู่ หากคุณต้องการใช้ทางลัดคุณต้องรู้ว่าการเข้ารหัสข้อมูลของคุณอยู่ในรูปแบบใด

UTF-16

เมื่อใดก็ตามที่ java พูดถึงตัวละครในเอกสารมันจะพูดถึงอักขระ 16 บิต

คุณสามารถใช้ a DataInputStreamซึ่งมีวิธีการที่สะดวก เพื่อประสิทธิภาพให้ห่อด้วยBufferedReader.

// e.g. for sockets
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
char character = readChar(); // no need to cast

สิ่งนี้คือแต่ละตัวreadChar()จะแสดง 2 readและรวมเป็นอักขระ 16 บิตหนึ่งตัว

ASCII สหรัฐอเมริกา

US-ASCII สงวน 8 บิตเพื่อเข้ารหัส 1 อักขระ ตาราง ASCII อธิบายเฉพาะอักขระที่เป็นไปได้ 128 อักขระดังนั้นจึงไม่ใช้ 1 บิตเสมอ

คุณสามารถแสดงในกรณีนี้ได้

int input = stream.read();
if (input < 0) throw new EOFException();
char character = (char) input;

ASCII แบบขยาย

UTF-8, Latin-1, ANSI และการเข้ารหัสอื่น ๆ ใช้ 8 บิตทั้งหมด 7 บิตแรกเป็นไปตามตาราง ASCII และเหมือนกับการเข้ารหัส US-ASCII อย่างไรก็ตามบิตที่ 8 นำเสนออักขระที่แตกต่างกันในการเข้ารหัสเหล่านี้ทั้งหมด ดังนั้นสิ่งต่างๆจึงน่าสนใจ

หากคุณเป็นคาวบอยและคุณคิดว่าบิตที่ 8 ไม่สำคัญ (เช่นคุณไม่สนใจตัวละครเช่น "à, é, ç, è, ô ... ) คุณก็สามารถหนีไปได้ด้วยการแคสง่ายๆ

อย่างไรก็ตามหากคุณต้องการดำเนินการอย่างมืออาชีพคุณควรระบุชุดอักขระทุกครั้งที่คุณนำเข้า / ส่งออกข้อความ (เช่นซ็อกเก็ตไฟล์ ... )

ใช้ชุดตัวอักษรเสมอ

เอาจริงเอาจังกันเถอะ ตัวเลือกทั้งหมดข้างต้นเป็นเทคนิคราคาถูก หากคุณต้องการเขียนซอฟต์แวร์ที่ยืดหยุ่นคุณต้องรองรับชุดอักขระที่กำหนดค่าได้เพื่อนำเข้า / ส่งออกข้อมูลของคุณ นี่คือวิธีแก้ปัญหาทั่วไป:

อ่านข้อมูลของคุณโดยใช้byte[]บัฟเฟอร์และการแปลงที่ไปใช้พารามิเตอร์String charset

byte[] buffer = new byte[1024];
int nrOfBytes = stream.read(buffer);
String result = new String(buffer, nrOfBytes, charset);

คุณยังสามารถใช้InputStreamReaderซึ่งสามารถสร้างอินสแตนซ์ด้วยพารามิเตอร์ charset

กฎทองอีกข้อหนึ่ง: อย่าโยนไบต์ให้กับตัวละครโดยตรง นั่นเป็นความผิดพลาดเสมอ


1

พิจารณาคำตอบของฉันอยู่บนสมมติฐานที่ว่าผู้ใช้เพียงแค่อยากจะ literaaly แปลงintที่จะcharยกตัวอย่างเช่น

Input: 
int i = 5; 
Output:
char c = '5'

นี้ได้รับการตอบรับแล้วข้างต้น แต่ถ้าค่าจำนวนเต็มแล้วจำเป็นต้องใช้i > 10char array

char[] c = String.valueOf(i).toCharArray();


0

ทั้งหมดนี้ขึ้นอยู่กับการเข้ารหัสข้อมูลขาเข้า


นี่คือ "คำตอบ" ที่ไร้ประโยชน์ฉันจะลงคะแนน แต่มันก็ไม่คุ้มค่าด้วยซ้ำ
Lpc_dark

@Lpc_dark คำตอบนี้ถูกต้องกว่า 90% ของคำตอบอื่น ๆ ดูคำตอบของฉันสำหรับรายละเอียดเพิ่มเติม
bvdb

0

อาจไม่ใช่สิ่งที่เร็วที่สุด:

//for example there is an integer with the value of 5:
int i = 5;

//getting the char '5' out of it:
char c = String.format("%s",i).charAt(0); 

-2

คำตอบสำหรับการแปลง char เป็น int หรือ long คือการหล่อแบบธรรมดา

ตัวอย่างเช่น: - หากคุณต้องการแปลง Char '0' เป็น long

ติดตามนักพากย์ง่ายๆ

Char ch='0';
String convertedChar= Character.toString(ch);  //Convert Char to String.
Long finalLongValue=Long.parseLong(convertedChar);

เสร็จสิ้น !!


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