我正在制作一个程序,将字符转换为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
答案 0 :(得分:1)
行后:
n = scan.nextInt();
添加以下行:
scan.nextLine()
然后,在您的第一个for循环中,使用
character[i] = scan.nextLine().charAt(0);
扫描仪将获得您每次输入的第一个字符,因此稍后转换为int将返回其ascii值。就像评论所说的那样,DataStream就是这里的问题。
答案 1 :(得分:1)
您的代码有两个问题。更大的问题是,DataInputStream
不会像您认为的那样阅读,另一个是您将两个资源连接到System.in
,即DataInputStream
和Scanner
。您应该使用Scanner
来阅读所有数据。
链接两者的问题是,DataInputStream
也会解释之前输入的4
,因为它仅由Scanner
使用,但也不由DataInputStream
使用。话虽如此,我无法重现您的确切值。如果我输入4
,然后输入a
,b
,c
,那么自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
如您所见,字节流包含的字符数不仅仅是a
,b
和c
,即\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\n
被Scanner
提供。
消除这种情况的最简单方法是使用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,您可以摆脱换行符。