Linux控制台,中文显示,中文输入

本文介绍了如何在Linux控制台实现中文显示和中文输入,通过zhcon项目进行本地化设置,详细阐述了从下载源代码到安装、使用的全过程,帮助Linux初学者和开发者创建便捷的中文环境。

Linux控制台,中文显示,中文输入
2007-12-02 22:43
一、前言
        Linux最初的开发完全是围绕ASCII编码体系进行的,没有考虑非英语用户面临的问题,因此导致其使用门槛较高,尤其对于亚洲用户而言,由于采用象形文字的特殊性(包括中文、韩文、日文,简称为CJK),使得对Linux进行本地化更为困难。在这样的背景下,ejoy等人发起了zhcon项目。该项目的目标是“为中文Linux使用者提供一个便捷易用的中文环境,特别适用于初学者,以及需要发布linux中文应用程序的开发者。”
 
 
二、安装
        现在最新版本是0.2.6。zhcon的源代码和RPM包可以从http://zhcon.sourceforge.net/下载得到。在 Sourceforger的网址http://sourceforge.net/project /showfiles.php?group_id=27400上,需要下载的文件有两个:一个是zhcon-0.2.5.tar.gz,一个是 zhcon-0.2.5-to-0.2.6.diff.gz。
 
    1.首先解压并解包zhcon-0.2.5.tar.gz文件:
[root@localhost zhcon]# tar zxvf zhcon-0.2.5.tar.gz
解压之后得到一个zhcon-0.2.5。这个目录包含了zhcon-0.2.5版本的所有源代码和man手册等。
 
    2.然后将zhcon-0.2.5-to-0.2.6.diff.gz解压:
[root@localhost zhcon]# gzip -d zhcon-0.2.5-to-0.2.6.diff.gz
解压后得到zhcon-0.2.5-to-0.2.6.diff文件,这个文件实际上是一个补丁文件。
 
    3.将zhcon-0.2.5-to-0.2.6.diff文件打补丁到zhcon-0.2.5的源代码中:
[root@localhost zhcon]# patch -p0 < zhcon-0.2.5-to-0.2.6.diff
在目录zhcon-0.2.5的父目录中进行这一步。

张建东注:或者

(3)进入解压后的zhcon.0.2.5目录
    cd zhcon.0.2.5
(4) 升级zhcon.0.2.5到zhcon.0.2.6
    patch -p1 < ../zhcon.0.2.5-0.2.6.diff   ----升级成功
 
这样,原来的0.2.5版本的zhcon就升级到了0.2.6版本了。接下来的过程就是UNIX平台固定的“安装三步曲”了:
[root@localhost zhcon]# ./configure --prefix=/usr/local/zhcon
 
[root@localhost zhcon]# make
 
[root@localhost zhcon]# make install
 
 
三、运用
       1.要想在控制台下显示中文,键入命令:
 
[root@localhost zhcon]# /usr/local/zhcon/bin/zhcon --utf8
 
即可。
 
    2.要想在控制台下运用中文输入法:
使用Ctrl+space或Ctrl+2来打开或关闭智能拼音输入法

注:我这个机器只能使用Ctrl+2打开或关闭全拼;Ctrl+space 不能使用。

<think>我们之前用Java实现的UDP聊天程序在控制台输入中文显示问号(?),这通常是由于字符编码不一致导致的。 在Java中,字符串默认使用Unicode编码,但在转换为字节数组(byte[])时,我们使用的是平台默认的字符编码(例如,在Windows上可能是GBK,而在Mac或Linux上可能是UTF-8)。如果发送方和接收方使用的编码方式不一致,或者控制台的编码不支持,就会导致乱码。 解决方案: 1. 在将字符串转换为字节数组时,指定统一的字符编码(如UTF-8)。 2. 确保接收方在将字节数组转换为字符串时也使用相同的编码。 修改代码: 在发送消息时,使用`String.getBytes(StandardCharsets.UTF_8)`指定编码。 在接收消息时,使用`new String(packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8)`指定编码。 同时,确保控制台支持UTF-8编码。如果控制台不支持(如Windows的cmd默认是GBK),则可能需要调整控制台编码,或者在IDE中设置。 以下是修改后的代码(仅修改了发送和接收时指定编码的部分,并导入必要的包): </think> # 中文乱码问题分析与解决方案 当使用Java控制台输入中文显示`?`时,问题通常是由字符编码不匹配引起的。下面是详细分析和解决方案: ## 问题原因 1. **控制台编码问题**:Windows系统默认使用GBK编码,而程序可能使用UTF-8 2. **Scanner读取问题**:Scanner默认使用平台编码读取输入 3. **字节转换问题**:字符串与字节数组转换时未指定编码 4. **网络传输问题**:UDP传输中未统一编解码方式 ## 完整解决方案 ```java import java.io.*; import java.net.*; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class FixedUDPChat { // 使用UTF-8编码常量 private static final String CHARSET = "UTF-8"; // 服务器端实现 static class Server { private static final int SERVER_PORT = 8888; public static void main(String[] args) { try (DatagramSocket socket = new DatagramSocket(SERVER_PORT)) { System.out.println("服务器启动,监听端口: " + SERVER_PORT); // 接收消息线程 new Thread(() -> { byte[] buffer = new byte[1024]; while (true) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); try { socket.receive(packet); // 使用UTF-8解码 String msg = new String( packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8 ); System.out.println("\n客户端说: " + msg); } catch (IOException e) { e.printStackTrace(); } } }).start(); // 发送消息线程 new Thread(() -> { Scanner scanner = new Scanner(System.in, CHARSET); // 指定输入编码 while (true) { System.out.print("服务器输入: "); String message = scanner.nextLine(); try { InetAddress clientAddress = InetAddress.getByName("localhost"); // 使用UTF-8编码 byte[] data = message.getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket( data, data.length, clientAddress, Client.CLIENT_PORT ); socket.send(packet); } catch (Exception e) { e.printStackTrace(); } } }).start(); } catch (SocketException e) { e.printStackTrace(); } } } // 客户端实现 static class Client { public static final int CLIENT_PORT = 9999; public static void main(String[] args) { try (DatagramSocket socket = new DatagramSocket(CLIENT_PORT)) { System.out.println("客户端启动,监听端口: " + CLIENT_PORT); // 接收消息线程 new Thread(() -> { byte[] buffer = new byte[1024]; while (true) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); try { socket.receive(packet); // 使用UTF-8解码 String msg = new String( packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8 ); System.out.println("\n服务器说: " + msg); } catch (IOException e) { e.printStackTrace(); } } }).start(); // 发送消息线程 new Thread(() -> { Scanner scanner = new Scanner(System.in, CHARSET); // 指定输入编码 while (true) { System.out.print("客户端输入: "); String message = scanner.nextLine(); try { InetAddress serverAddress = InetAddress.getByName("localhost"); // 使用UTF-8编码 byte[] data = message.getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket( data, data.length, serverAddress, Server.SERVER_PORT ); socket.send(packet); } catch (Exception e) { e.printStackTrace(); } } }).start(); } catch (SocketException e) { e.printStackTrace(); } } } } ``` ### 关键修改点解释 1. **统一使用UTF-8编码**: - 在`Scanner`创建时指定编码:`new Scanner(System.in, "UTF-8")` - 发送数据时:`message.getBytes(StandardCharsets.UTF_8)` - 接收数据时:`new String(..., StandardCharsets.UTF_8)` 2. **正确使用DatagramPacket参数**: - 使用`packet.getOffset()`和`packet.getLength()`确保只处理有效数据 - 避免处理缓冲区中未初始化的部分 3. **导入正确的类**: - `import java.nio.charset.StandardCharsets` 提供标准字符集常量 ### 额外配置建议 1. **IDE控制台设置**: - 在IntelliJ IDEA中:File > Settings > Editor > File Encodings - 设置Global Encoding、Project Encoding和Default encoding为UTF-8 - 勾选"Transparent native-to-ascii conversion" 2. **系统环境设置**: ```bash # Windows命令提示符设置UTF-8 chcp 65001 # Linux/Mac终端设置 export LANG=en_US.UTF-8 ``` 3. **编译参数**: ```bash javac -encoding UTF-8 FixedUDPChat.java ``` ### 验证中文支持 1. 启动服务器端: ```bash java FixedUDPChat$Server ``` 2. 启动客户端: ```bash java FixedUDPChat$Client ``` 3. 在任意一方输入中文,如"你好,世界!",另一方应能正确显示 ## 中文乱码的其他可能原因 1. **字体不支持中文字符**: - 检查控制台使用的字体是否支持中文(如SimSun、Microsoft YaongHei) 2. **网络传输损坏**: - UDP协议不保证可靠传输,大数据包可能被拆分或丢失 - 考虑添加数据校验机制 3. **操作系统区域设置**: - 确保操作系统区域设置为中文区域 - Windows:控制面板 > 区域 > 管理 > 更改系统区域设置 > 勾选"Beta: 使用Unicode UTF-8"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值