Scanner sc = new Scanner(System.in);
System.out.println("Enter text: ");
String text = sc.nextLine();
try {
String result = new String(text.getBytes("windows-1251"), Charset.forName("UTF-8"));
System.out.println(result);
} catch (UnsupportedEncodingException e) {
System.out.println(e);
}
我正在尝试更换键盘:输入cyrylic键盘,输出拉丁语。示例:qwerty +> йцукен
它不起作用,谁能告诉我我做错了什么?
答案 0 :(得分:3)
第一个java文本,String / char / Reader / Writer是内部Unicode,因此它可以组合所有脚本。 这与例如没有这种标准的C / C ++有很大的不同。
现在,由于历史原因,System.in是一个InputStream。这需要使用编码的指示。
Scanner sc = new Scanner(System.in, "Windows-1251");
上面明确地将System.in的转换设置为Cyrillic。如果没有此可选参数,则采用默认编码。如果软件没有改变,那就是平台编码。所以这也可能是正确的。
现在text
是正确的,包含来自System.in的Cyrillic作为Unicode。
您将获得UTF-8字节:
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
旧的"重新编码"文字错了;放弃这一行。实际上并非所有Windows-1251字节都是有效的UTF-8多字节序列。
String result = text;
System.out.println(result);
System.out是一个PrintStream,一个很少使用的历史类。它使用默认平台编码进行打印。或多或少地依赖它,默认编码是正确的。
System.out.println(result);
用于打印到UTF-8编码文件:
byte[] bytes = ("\uFEFF" + text).getBytes(StandardCharsets.UTF_8);
Path path = Paths.get("C:/Temp/test.txt");
Files.writeAllBytes(path, bytes);
这里我在前面添加了一个Unicode BOM字符,因此Windows Notepad可能会将编码识别为UTF-8。一般来说,应该使用BOM来逃避。它是一个零宽度的空间(=不可见)并且会破坏各种格式:CSV,XML,文件串联,剪切复制粘贴。
答案 1 :(得分:1)
你之所以得到另一个问题的答案,没有人回答你的问题,是因为你的头衔不适合这个问题。您没有尝试在字符集之间进行转换,而是在键盘布局之间进行转换。
在这里你根本不用担心字符布局,只需读取该行,将其转换为字符数组,浏览它们并使用预定义的地图转换它们。
代码将是这样的:
Map<char, char> table = new TreeMap<char, char>();
table.put('q', 'й');
table.put('Q', 'Й');
table.put('w', 'ц');
// .... etc
String text = sc.nextLine();
char[] cArr = text.toCharArray();
for(int i=0; i<cArr.length; ++i)
{
if(table.containsKey(cArr[i]))
{
cArr[i] = table.get(cArr[i]);
}
}
text = new String(cArr);
System.out.println(text);
现在,我没有时间测试该代码,但您应该了解如何完成任务。