Convertendo stream de int's para char's em java

114

Isso provavelmente já foi respondido em outro lugar, mas como você obtém o valor do caractere de um valor int?

Especificamente, estou lendo um de um fluxo tcp e o método .read () dos leitores retorna um int.

Como faço para obter um caractere disso?

Omar Kooheji
fonte
1
Você não entrou em detalhes sobre quais dados está enviando e lendo. Você envia bytes binários ou caracteres Unicode? O método leitores .read () retorna um int. Sim, mas retorna o caractere lido, como um inteiro no intervalo de 0 a 65535 (ou -1, isso porque acho que int usado em vez de char). Talvez só o uso public int read(char[] cbuf)resolva o problema?
Vanuan
As respostas para esta pergunta não funcionam para JSP Java. Se você estiver usando jsp, consulte este bug de estouro de pilha: stackoverflow.com/questions/4621836/…
NuclearPeon
Eu acho que esta é uma pergunta válida. Uma das dificuldades de converter um inteiro em um caractere é lidar com valores negativos e valores> = 255.
bvdb
E se eu quiser converter um byte que está em uma matriz de bytes em um caractere e depois imprimi-lo no console?
Doug Hauf

Respostas:

74

Se você está tentando converter um fluxo em texto, precisa estar ciente de qual codificação deseja usar. Você pode então passar um array de bytes para o Stringconstrutor e fornecer um Charset, ou usar InputStreamReadercom o apropriado Charset.

A simples transmissão de intpara charsó funciona se você quiser ISO-8859-1, se estiver lendo bytes de um fluxo diretamente.

EDITAR: se você já estiver usando um Reader, então lançar o valor de retorno de read()para charé o caminho certo (depois de verificar se é -1 ou não) ... mas normalmente é mais eficiente e conveniente chamar read(char[], int, int)para ler um bloco inteiro de texto de cada vez. Não se esqueça de verificar o valor de retorno, para ver quantos caracteres foram lidos.

Jon Skeet
fonte
2
Acho que não é sobre isso que o OP está perguntando. Ele está usando o método de leitura do Reader: java.sun.com/j2se/1.4.2/docs/api/java/io/Reader.html#read () A pergunta que ele está fazendo é como converter o valor retornado por este método em char .
Vanuan
3
Se ele estiver usando o Reader genuinamente, isso certamente fará diferença. Não está claro, já que ele fala sobre um stream e um leitor (com r minúsculo) na mesma frase :( Editei minha resposta para deixar isso claro.
Jon Skeet
você também pode envolver o InputStreamReaderem a BufferedReader, conforme mencionado no javadoc docs.oracle.com/javase/8/docs/api/java/io/…
bvdb
Por que "simplesmente lançar de int para char só funciona se você quiser ISO-8859-1"? É porque o Java usa UTF-16 internamente e todos os caracteres ISO-8859-1 mantêm a mesma unidade de código (bits) em UTF-16?
Sébastien
@Sebastien: Sim, é basicamente isso.
Jon Skeet
144

Talvez você esteja pedindo:

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

Mais informações: Character.toChars(int codePoint)

Converte o caractere especificado (ponto de código Unicode) em sua representação UTF-16 armazenada em uma matriz char. Se o ponto de código especificado for um valor BMP (Basic Multilingual Plane ou Plane 0), a matriz char resultante terá o mesmo valor que codePoint. Se o ponto de código especificado for um ponto de código suplementar, a matriz de char resultante terá o par substituto correspondente.

ATorras
fonte
9
Isso só é válido se o inteiro em questão já for um ponto de código UTF-16. Não temos ideia se é esse o caso.
Jon Skeet
2
@Atec: Não, meu ponto é que, se ele está apenas lendo bytes de um stream (não está claro), a conversão apenas lançando ou usando toCharsgeralmente é inadequada. Se ele está lendo de um Reader, tudo bem.
Jon Skeet
2
Embora reconhecidamente a questão não o especifica, esta questão surge como o primeiro resultado de uma pesquisa no Google para converter pontos de código ASCII em caracteres, por isso estou votando a favor.
ArtOfWarfare
105

Depende do que você entende por "converter um int em char".

Se você simplesmente deseja lançar o valor no int, pode lançá-lo usando a notação typecast do Java:

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

Se você quer transformar o inteiro 1 no caractere '1', pode fazer assim:

if (i >= 0 && i <= 9) {
char c = Character.forDigit(i, 10);
....
}
Lovubuntu
fonte
E se você fosse de Char para Integer? Integer.parseInt (c)?
Breedly
Esta resposta é A única :-)
voghDev
29

Se você deseja simplesmente converter int 5 em char '5': (somente para inteiros 0 - 9)

int i = 5;
char c = (char) ('0' + i); // c is now '5';
Ryan Anderson
fonte
Não .. '0' + 5 torna-se a string '05'. O lado direito deve ser (char) ((int) '0') + i;
toddkaufmann
Não é verdade porque os caracteres não são convertidos em Strings em Java.
Kaushik Shankar
+1 - experimentado e testado, funciona! Tente e teste você mesmo, aparentemente ao contrário dos comentadores aqui ...
Ian Campbell
8

Elenco simples:

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

Existe alguma razão para que isso não esteja funcionando para você?

Yuval Adam
fonte
1
Conselho perigoso, se o fluxo de texto não for ASCII puro. Veja a resposta de Jon Skeet acima.
sleske
1
Pode não funcionar. Mas acho que sim. O tipo de dados char armazena o valor codificado em UTF-16. Então, para lançar char para int, você precisa fazer algumas transformações. Mas como o OP usa o método read (), que já retorna o valor codificado em UTF-16, a conversão simples funcionaria, eu acho. Corrija-me se eu estiver errado.
Vanuan
Desculpe, eu quis dizer "de int para char"
Vanuan
isso causará valores de codificação inesperados, não números
Vasil Valchev
4

Esta solução funciona para tamanho de comprimento inteiro = 1.

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

se o tamanho> 1, precisamos usar o loop e iterar.

Spiker
fonte
1

A maioria das respostas aqui propõe atalhos, que podem trazer grandes problemas se você não tiver ideia do que está fazendo. Se você quiser usar atalhos, precisa saber exatamente em que codificação seus dados estão.

UTF-16

Sempre que java fala sobre personagens em sua documentação, ele fala sobre personagens de 16 bits.

Você pode usar um DataInputStream, que possui métodos convenientes. Para maior eficiência, embrulhe-o em um BufferedReader.

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

O fato é que cada um readChar()irá realmente executar 2 read's e combiná-los em um caractere de 16 bits.

US-ASCII

US-ASCII reserva 8 bits para codificar 1 caractere. A tabela ASCII descreve apenas 128 caracteres possíveis, portanto, 1 bit está sempre não utilizado.

Você pode simplesmente executar um elenco neste caso.

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

ASCII estendido

UTF-8, Latin-1, ANSI e muitas outras codificações usam todos os 8 bits. Os primeiros 7 bits seguem a tabela ASCII e são idênticos aos da codificação US-ASCII. No entanto, o 8º bit oferece caracteres diferentes em todas essas codificações. Então, aqui as coisas ficam interessantes.

Se você é um cowboy e acha que o 8º bit não importa (ou seja, você não se importa com personagens como "à, é, ç, è, ô ...) então você pode se safar com um elenco simples.

No entanto, se você quiser fazer isso profissionalmente, você deve realmente SEMPRE especificar um conjunto de caracteres sempre que importar / exportar texto (por exemplo, sockets, arquivos ...).

Sempre use conjuntos de caracteres

Vamos falar sério. Todas as opções acima são truques baratos. Se você deseja escrever um software flexível, você precisa oferecer suporte a um conjunto de caracteres configurável para importar / exportar seus dados. Aqui está uma solução genérica:

Leia seus dados usando um byte[]buffer e converta-os em um String parâmetro charset .

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

Você também pode usar um InputStreamReaderque pode ser instanciado com um parâmetro charset.

Só mais uma regra de ouro: nunca lance um byte diretamente para um personagem. Isso sempre é um erro.

bvdb
fonte
1

Baseando minha resposta na suposição de que o usuário queria apenas converter literalmente um intpara char, por exemplo

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

Isso já foi respondido acima, porém se for o valor inteiro i > 10, então precisa usar char array.

char[] c = String.valueOf(i).toCharArray();
src3369
fonte
1
    int i = 7;
    char number = Integer.toString(i).charAt(0);
    System.out.println(number);
Shwarz Andrei
fonte
0

Isso depende inteiramente da codificação dos dados recebidos.


fonte
Isso é como uma "resposta" inútil, eu votaria contra, mas nem vale a pena.
Lpc_dark 02 de
@Lpc_dark Esta resposta é mais correta do que 90% das outras respostas. Veja minha resposta para mais detalhes.
bvdb
0

talvez não seja o mais rápido:

//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); 
Guest89898989
fonte
-2

A resposta para a conversão de char em int ou long é a conversão simples.

Por exemplo: - se deseja converter o caractere '0' em longo.

Seguir elenco simples

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

Feito!!

Dheeraj Varne
fonte
isso é EXATAMENTE o oposto do que ele estava perguntando.
specializt