Konwersja strumienia int na char w java


114

Na to prawdopodobnie udzielono odpowiedzi gdzie indziej, ale jak uzyskać wartość znaku wartości int?

W szczególności czytam ze strumienia TCP, a metoda readers .read () zwraca wartość int.

Jak mogę z tego zdobyć chara?


1
Nie sprecyzowałeś, jakie dane wysyłasz i czytasz. Czy wysyłasz binarne bajty czy znaki Unicode? Metoda readers .read () zwraca int. Tak, ale zwraca odczytany znak jako liczbę całkowitą z zakresu od 0 do 65535 (lub -1, ponieważ myślę, że zamiast znaku użyto int). Może samo użycie public int read(char[] cbuf)rozwiąże problem?
Vanuan

Odpowiedzi na to pytanie nie działają w przypadku JSP Java. Jeśli używasz jsp, zobacz ten błąd przepełnienia stosu: stackoverflow.com/questions/4621836/ ...
NuclearPeon

Myślę, że to ważne pytanie. Jedną z trudności związanych z konwersją liczby całkowitej na znak jest radzenie sobie z wartościami ujemnymi i wartościami> = 255.
bvdb

Co się stanie, jeśli chcę przekonwertować bajt znajdujący się w tablicy bajtów na znak, a następnie wydrukować go na konsoli?
Doug Hauf

Odpowiedzi:


74

Jeśli próbujesz przekonwertować strumień na tekst, musisz wiedzieć, jakiego kodowania chcesz użyć. Następnie możesz przekazać tablicę bajtów do Stringkonstruktora i podać a Charsetlub użyć zamiast tego InputStreamReaderodpowiedniego Charset.

Po prostu rzutowanie z intdo chardziała tylko wtedy, gdy chcesz ISO-8859-1, jeśli bezpośrednio czytasz bajty ze strumienia.

EDIT: Jeśli już za pomocą Reader, a następnie rzucając wartość zwracaną read()na charto właściwa droga (po sprawdzeniu czy jest -1 lub nie) ... ale to jest zwykle bardziej wydajne i wygodne zadzwonić read(char[], int, int), aby przeczytać cały blok tekst na raz. Nie zapomnij jednak sprawdzić zwracanej wartości, aby zobaczyć, ile znaków zostało odczytanych.


2
Myślę, że nie o to pyta PO. Używa metody Reader's read: java.sun.com/j2se/1.4.2/docs/api/java/io/Reader.html#read () Pytanie, które zadaje, brzmi: jak zamienić wartość zwracaną przez tę metodę na znak .
Vanuan

3
Jeśli naprawdę używa Czytnika, to z pewnością ma znaczenie. Nie jest to jasne, biorąc pod uwagę, że mówi o strumieniu i czytelniku (małą literą r) w tym samym zdaniu :( Zredagowałem moją odpowiedź, aby to wyjaśnić.
Jon Skeet

możesz również zawinąć InputStreamReaderw a BufferedReader, jak wspomniano w dokumentacji javadoc docs.oracle.com/javase/8/docs/api/java/io/…
bvdb

Dlaczego jest tak, że „Proste przesyłanie z int na char działa tylko wtedy, gdy chcesz ISO-8859-1”? Czy dzieje się tak, ponieważ Java używa wewnętrznie UTF-16, a wszystkie znaki ISO-8859-1 zachowują tę samą jednostkę kodu (bity) w UTF-16?
Sébastien

@Sebastien: Tak, w zasadzie to wszystko.
Jon Skeet

144

Może prosisz o:

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

Więcej informacji: Character.toChars(int codePoint)

Konwertuje określony znak (punkt kodowy Unicode) na jego reprezentację w formacie UTF-16 przechowywaną w tablicy char. Jeśli określony punkt kodowy jest wartością BMP (Basic Multilingual Plane lub Plane 0), wynikowa tablica znaków ma taką samą wartość jak codePoint. Jeśli określony punkt kodowy jest dodatkowym punktem kodowym, wynikowa tablica znaków ma odpowiednią parę zastępczą.


9
Jest to ważne tylko wtedy, gdy dana liczba całkowita jest już punktem kodowym UTF-16. Nie mamy pojęcia, czy tak jest.
Jon Skeet

2
@Atec: Nie, chodzi mi o to, że jeśli on po prostu czyta bajty ze strumienia (nie jest to jasne), konwersja przez zwykłe przesyłanie lub użycie toCharsjest zwykle niewłaściwa. Jeśli czyta od Czytelnika, to w porządku.
Jon Skeet

2
Chociaż wprawdzie pytanie tego nie określało, to pytanie pojawia się jako pierwszy wynik wyszukiwania Google w celu konwersji punktów kodowych ASCII na znaki, więc głosuję za nim.
ArtOfWarfare

105

To zależy od tego, co masz na myśli, mówiąc „zamień int na znak”.

Jeśli chcesz po prostu rzutować wartość w int, możesz ją przesłać za pomocą notacji typecast Java:

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

Jeśli masz na myśli przekształcenie liczby całkowitej 1 w znak „1”, możesz to zrobić w następujący sposób:

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

A co by było, gdybyś jechał z Char do Integer? Integer.parseInt (c)?
Breedly

To ta odpowiedź :-)
voghDev

29

Jeśli chcesz po prostu przekonwertować int 5 na char '5': (Tylko dla liczb całkowitych 0 - 9)

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

Nie .. „0” + 5 staje się ciągiem „05”. Prawa strona powinna być (char) ((int) '0') + i;
toddkaufmann

Nieprawda, ponieważ znaki nie są konwertowane na ciągi w Javie.
Kaushik Shankar,

+1 - wypróbowane i przetestowane, działa! Spróbuj i przetestuj to sam, pozornie w przeciwieństwie do komentatorów tutaj ...
Ian Campbell,

8

Proste odlewanie:

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

Czy jest jakiś powód, dla którego to nie działa?


1
Niebezpieczna rada, jeśli strumień tekstowy nie jest czystym ASCII. Zobacz odpowiedź Jona Skeeta powyżej.
sleske

1
To może nie zadziałać. Ale myślę, że faktycznie tak. Typ danych char przechowuje zakodowaną wartość UTF-16. Więc aby rzucić char na int, musisz wykonać kilka transformacji. Ale ponieważ OP używa metody read (), która już zwraca zakodowaną wartość UTF-16, myślę, że proste rzutowanie działałoby. Popraw mnie, jeśli się mylę.
Vanuan

Przepraszam, miałem na myśli „od int do char”
Vanuan

spowoduje to nieoczekiwane wartości kodowania, a nie liczby
Vasil Valchev

4

To rozwiązanie działa dla długości całkowitej rozmiar = 1.

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

jeśli rozmiar> 1, musimy użyć pętli i wykonać iterację.


1

Większość odpowiedzi przedstawia tutaj skróty, które mogą przynieść duże problemy, jeśli nie masz pojęcia, co robisz. Jeśli chcesz iść na skróty, musisz dokładnie wiedzieć, w jakim kodowaniu są Twoje dane.

UTF-16

Ilekroć java mówi o znakach w swojej dokumentacji, mówi o znakach 16-bitowych.

Możesz użyć DataInputStream, który ma wygodne metody. Aby uzyskać wydajność, zawiń go w BufferedReader.

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

Chodzi o to, że każdy readChar()faktycznie wykona 2 readi połączy je w jeden 16-bitowy znak.

US-ASCII

US-ASCII rezerwuje 8 bitów do zakodowania 1 znaku. Tabela ASCII opisuje jednak tylko 128 możliwych znaków, więc 1 bit jest zawsze nieużywany.

W takim przypadku możesz po prostu wykonać rzut.

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

Rozszerzony ASCII

UTF-8, Latin-1, ANSI i wiele innych kodowań wykorzystuje wszystkie 8-bitowe. Pierwsze 7 bitów jest zgodne z tabelą ASCII i jest identyczne z kodowaniem US-ASCII. Jednak ósmy bit oferuje znaki, które są różne we wszystkich tych kodowaniach. Więc tutaj robi się ciekawie.

Jeśli jesteś kowbojem i uważasz, że ósmy bit nie ma znaczenia (tj. Nie przejmujesz się postaciami typu „à, é, ç, è, ô…), możesz uciec z prostą obsadą.

Jeśli jednak chcesz to zrobić profesjonalnie, powinieneś ZAWSZE określić zestaw znaków za każdym razem, gdy importujesz / eksportujesz tekst (np. Gniazda, pliki ...).

Zawsze używaj zestawów znaków

Bądźmy poważni. Wszystkie powyższe opcje to tanie sztuczki. Jeśli chcesz pisać elastyczne oprogramowanie, musisz obsługiwać konfigurowalny zestaw znaków do importowania / eksportowania danych. Oto ogólne rozwiązanie:

Odczytaj dane używając byte[]bufora i przekonwertuj je na String parametr charset .

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

Możesz także użyć, InputStreamReaderktórego instancję można utworzyć za pomocą parametru charset.

Jeszcze jedna złota zasada: nigdy nie rzucaj bajtu bezpośrednio na postać. To zawsze błąd.


1

Opierając moją odpowiedź na założeniu, że użytkownik po prostu chciał literaaly Konwersja intdo char, na przykład

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

Na to już odpowiedziano powyżej, jednak jeśli wartość całkowita i > 10, należy użyć char array.

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


0

Jest to całkowicie zależne od kodowania przychodzących danych.


jest to takie jak bezużyteczna „odpowiedź”, głosowałbym w dół, ale to nawet nie jest tego warte.
Lpc_dark,

@Lpc_dark Ta odpowiedź jest bardziej poprawna niż 90% innych odpowiedzi. Zobacz moją odpowiedź, aby uzyskać więcej informacji.
bvdb

0

może nie najszybszy:

//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

Odpowiedzią na konwersję char na int lub long jest proste rzucanie.

Na przykład: - jeśli chcesz zamienić znak '0' na długi.

Postępuj zgodnie z prostą obsadą

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

Gotowe!!


to DOKŁADNIE przeciwieństwo tego, o co prosił.
specializt
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.