将char转换为ASCII不起作用

时间:2017-12-16 13:51:22

标签: java ascii

我正在制作一个程序,将字符转换为ASCII码。

用户将输入字符,然后这些字符将存储到数组中,程序会将这些字符转换为ASCII值。

以下是我的代码:

package chartoascii;

import java.io.DataInputStream;
import java.io.IOException;

public class CharToAscii {

    public static void main(String[] args) throws IOException 
    {
        DataInputStream in=new DataInputStream(System.in);
        int n;
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter number of Characters you want to insert : ");
        n = scan.nextInt();
        char character[] = new char[n];
        System.out.println("Enter Characters : ");
        for (int i=0; i<n; i++)
        {
            character[i] = in.readChar() ;
        } // for loop

        for (int i=0; i<character.length; i++)
        {
           int ascii = (int) character[i];
           System.out.println(ascii);
        }
    }

}

我的程序运行正常,但我得到的输出是 ASCII码。

这是我的输出:

Enter number of Characters you want to insert : 
4
Enter Characters : 
a
b
c
d
24842
25098
25354
25610

3 个答案:

答案 0 :(得分:1)

行后:

n = scan.nextInt();

添加以下行:

scan.nextLine()

然后,在您的第一个for循环中,使用

character[i] = scan.nextLine().charAt(0);

扫描仪将获得您每次输入的第一个字符,因此稍后转换为int将返回其ascii值。就像评论所说的那样,DataStream就是这里的问题。

答案 1 :(得分:1)

说明

您的代码有两个问题。更大的问题是,DataInputStream不会像您认为的那样阅读,另一个是您将两个资源连接到System.in,即DataInputStreamScanner。您应该使用Scanner来阅读所有数据。

链接两者的问题是,DataInputStream也会解释之前输入的4,因为它仅由Scanner使用,但也不由DataInputStream使用。话虽如此,我无法重现您的确切值。如果我输入4,然后输入abc,那么自d以来我也无法输入DataInputStream读取4(我认为原因是您的计算机使用\n表示换行符和\r\n}。所以最后的输入是

4
a
b
c

如果我调整你的循环以显示它打印的(作为字符):

for (int i = 0; i < character.length; i++) {
    int ascii = (int) character[i];
    System.out.println(character[i] + " -> " + ascii);
}

我明白了:

? -> 24845
? -> 2658
? -> 3338
? -> 25357

好的,为什么所有?而不是正确的输入呢?因此,我们需要了解DataInputStream#readChar的工作原理。根据其documentation

  

返回:此输入流的下一个两个字节,被解释为char。

然而,为了获得ASCII值,我们需要解释类似ASCII的字节流。 ASCII也是固定长度,但每个字符一个字节而不是两个。但是,如果您还希望能够读取äé甚至等不同字符,则需要解释字节流不是固定长度,而是使用某种编码方案像UTF-16。现在请注意,UTF-16 不是固定长度

为了理解这些值,让我们看看确切的字节流,我们有

01100001 00001101 // ? -> 24845
00001010 01100010 // ? -> 2658
00001101 00001010 // ? -> 3338
01100011 00001101 // ? -> 25357

如你所见,如果我们安排像这样的字节(总是两个字节),我们得到十进制格式的相应值。对于ASCII,我们需要重新排列字节并按如下方式读取:

01100001  //  a -> 97
00001101  // \r -> 13
00001010  // \n -> 10
01100010  //  b -> 98
00001101  // \r -> 13
00001010  // \n -> 10
01100011  //  c -> 99
00001101  // \r -> 13

如您所见,字节流包含的字符数不仅仅是abc,即\r\n。这两个被解释为换行符 - 命令,因此请参阅Wikipedia

解决方案

最简单的解决方法是使用Scanner及其next方法(documentation)。此方法会自动阻止,直到输入下一个完整标记。这由分隔符模式决定。要为一个UTF-16字符设置它,我们只需用空String分隔(因此请查看Take a char input from the Scanner):

Scanner scanner = new Scanner(System.in);
scanner.useDelimiter("");

之后,您可以阅读4 String个值。但是,我们仍有问题\r\nScanner提供。

消除这种情况的最简单方法是使用Scanner#nextLine代替(documentation)。因此,我们不是只阅读一个字符,而是阅读整行。该方法会自动为我们抛出\r\n

Scanner scanner = new Scanner(System.in);

System.out.println("Enter number of Characters you want to insert : ");
int n = Integer.parseInt(scanner.nextLine());

char[] character = new char[n];
System.out.println("Enter Characters : ");
for (int i = 0; i < n; i++) {
    // Only use first character of line
    character[i] = scanner.nextLine().charAt(0);
}

for (int i = 0; i < character.length; i++) {
    int ascii = (int) character[i];
    System.out.println(character[i] + " -> " + ascii);
}

现在正确打印ASCII值

a -> 97
b -> 98
c -> 99
d -> 100

准确地说,它打印UTF-16值,但ASCII包含在UTF-16中。

答案 2 :(得分:0)

您在每个字母后面输入了另一个字符:换行符(U000a)。这与上面提到的错误一起,readChar误导性地没有按照其名称进行的操作,给出了您收到的值:25098是十六进制x620a,x66是b,x0a是换行。通过使用readLine,您可以摆脱换行符。