最近,学习又从新开始Linux学习,因此一直在Centos中,昨天一朋友把他在Windows下写的C程序发给我,我欣然答应,本觉得很快就能在个人Linux系统中运行起来。没想到出现了乱码,结果想把这个问题解决,一会儿就搞了近三个小时没有解决。今天,又想起来这个问题,居然一会儿就解决了,如今把学到的一些东西总结以下。html
首先Windows下的文件拿到Linux中来查看出现乱码是一种很常见的现象,这方面的资料在网上也有不少。但解决方法大多都相似,有些概念没有解释清楚,也许是我的没有理解清楚。linux
尝试方法一:sql
一碰到这个问题,我想到的是Linux课上学到的一个命令dos2unix,之前也没用过,此次用了也没有解决问题。shell
由于,这个命令主要是用来处理Dos与Linux之间断行的差别的。DOS下的文本文件是以\r\n做为断行标志的,表示成十六进制就是0D 0A。而Unix下的文本文件是以\n做为断行标志的,表示成十六进制就是 0A。有时咱们会遇到这样一种状况,dos下的文件在unix下显示是不出现断行,显得很乱,这时用这个命令就OK。数据库
后来在网上查了下,知道是编码格式不一致致使的。由于Dos下编辑的文本默认是以GBK存储的,而Linux默认采起的存储方式是UTF-8,固然会出现乱码了,可是如何去将Dos下的GBK文件转换成UTF-8呢?vim
尝试方法二:更改Vim读取时采用的编码windows
先补充一个知识,参考博客http://blog.csdn.net/kl222/article/details/4550269bash
vim编码方面的基础知识:
存在3个变量:
encoding—-该选项使用于缓冲的文本(你正在编辑的文件),寄存器,Vim 脚本文件等等。你能够把 'encoding' 选项看成是对 Vim 内部运行机制的设定。
fileencoding—-该选项是vim写入文件时采用的编码类型。
termencoding—-该选项表明输出到客户终端(Term)采用的编码类型。服务器
因此,我尝试了在Vim中session
:set encoding
:set fileencoding=utf-8 #让Vim将gbk的文本转换成utf-8后,显示出来
通过这样改了以后,果真,Vim中看到的乱码消失了,此时心情小小的激动了一会儿。
可是,当我退出Vim再次打开文件时,乱码又出现了,原来是我更改的Vim设置只是临时的,因此我决定将其写死到vim配置文件当中去,操做以下:
编辑~/.vimrc文件,加上以下几行:
set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8
这时,每次用Vim打开文件时都不出现乱码了,本觉得问题解决了,我开始编译程序,当我运行的时候,乱码仍是出现了。。。。此时,欲哭无泪
后来,我仔细想了一下,我更改Vim的配置,只是让咱们看到的没有乱码,但从根本上讲,文件的编码方式仍是没有变,因此当我用gcc编译后,文件的编码格式应该仍是gbk的。这样致使的乱码。因此,我决定找个工具,直接讲gbk文件转换成utf-8。
尝试三:
1.查看文件存储格式
#file test.cpp
test.cpp: ISO-8859 English text, with CRLF line terminators
能够看出文件是以ISO-8859存储的。
2.查看系统语言设置
#cat /etc/sysconfig/i18n
LANG="en_US.UTF-8"
SYSFONT="latarcyrheb-sun16"
能够看出Linux是以UTF-8编码的
3.利用工具将文件从ISO-8859转换成UTF-8(这里我采用的是iconv命令)
#iconv -f ISO-8859 -t UTF-8 test.c -o test_u.c
这时居然出现了一个错误:
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage
解决方案:
将ISO-8859换成GBK
#iconv -f GBK -t UTF-8 test.c -o test_u.c
终于大功告成!
参考文献:
[1].http://blog.csdn.net/kl222/article/details/4550269
[2].http://www.cnblogs.com/cosiray/archive/2012/05/04/2483111.html
[3].http://blog.chinaunix.net/uid-26786246-id-3636785.html
要解决Oracle的客户端乱码问题关键是要把服务器端使用的字符集跟客户端使用的字符集统一块儿来。Oracle客户端(Sqlplus)经过NLS_LANG环境变量来肯定客户端使用的字符集。NLS_LANG参数由如下部分组成:
NLS_LANG=<Language>_<Territory>.<Clients Characterset>
NLS_LANG各部分含义以下:
LANGUAGE指定:
-Oracle消息使用的语言
-日期中月份和日显示
TERRITORY指定
-货币和数字格式
-地区和计算星期及日期的习惯
CHARACTERSET:
-控制客户端应用程序使用的字符集
一般设置或者等于客户端(如Windows)代码页
或者对于unicode应用设置为UTF8
RedHat linux AS4.0安装了oracle10g,同时建立数据库实例sc,后来又用dbca创建一个数据库实例st,发如今oracle系统用户下用sqlplus链接st实例时出现乱码,应该是中文没法显示形成的,但链接sc实例时无乱码,显示英文。上网搜集了一下资料,修改了oracle系统用户的环境变量在.bash_profile中新增了如下内容解决:
export NLS_LANG=AMERICAN_AMERICA.UTF8
export LANG=en_US.UTF-8
分析缘由:
引用网上帖子:
oracle字符集问题通常能够分为三类: 数据库字符集, sqlplus的字符集(客户端字符集), 终端程序的字符集(非oracle的)。
一、数据库字符集。
数据库字符集是全部字符问题的核心,只有数据库自己的字符集正确了,客户端的字符集才可能正确。这里只的客户端包括sqlplus以及咱们本身读数据库的应用程序。
在定位问题时,咱们须要先看看数据库当前是什么字符集。
1)查询数据库字符集
select * from nls_database_parameters
其中 nls_language表示了显示方式, 就是sqlplus的程序的显示字体,有SIMPLIFIED CHINESE,American america
其中 nls_characterset是字符集设定, 经常使用的一些字符集有UTF8,US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK, AL32UTF8
2)修改数据库字符集
当发现数据库字符集不正确时,如咱们指望时GBK的,而数据库当前是其余的,从而引发中文乱码。这时咱们须要修改数据库字符集。步骤以下:
$sqlplus /nolog
SQL>conn / as sysdba;
若此时数据库服务器已启动,则先执行SHUTDOWN IMMEDIATE命令关闭数据库服务器,而后执行如下命令:
SQL>STARTUP MOUNT;
SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL>ALTER DATABASE OPEN;
SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;
SQL>ALTER DATABASE national CHARACTER SET ZHS16GBK;
SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP
2 客户端字符集
若是服务器端的字符集是正确的,而在客户端下,如sqlplus仍然不能正确显示中文,这通常是因为服务器端的字符集设定与客户端的字符集设定不一样形成的。只要将二者修改一致就能够解决问题。
1)查询客户端字符集
select * from nls_instance_parameters
客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter,
表示客户端的字符集的设置,多是参数文件,环境变量或者是注册表
select userenv('language') from dual;
会话字符集环境 select * from nls_session_parameters,其来源于v$nls_parameters,表示会话本身的设置,多是会话的环境变量或者是alter session完成,若是会话没有特殊的设置,将与nls_instance_parameters一致。
客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。若是多个设置存在的时候,alter session>环境变量>注册表>参数文件
字符集要求一致,可是语言设置却能够不一样,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang能够是American_America.zhs16gbk。 或者.zhs16gbk。注意zhs16gbk前面那个点是必须的哦!!
2) 修改客户端字符集
oracle 的sqlplus会去读取OS中环境变量下的nls_lang信息(关键在这里,经过以上命令查看
select * from nls_database_parameters 显示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
select * from nls_instance_parameters 显示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
select * from nls_session_parameters 显示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
也就是说会话字符集与终端字符集一致,而与数据库字符集设置不一致。
另外一个数据库实例sc
数据库字符集
select * from nls_database_parameters 显示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
select * from nls_instance_parameters 显示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
在linux下
select * from nls_session_parameters 显示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
用TOD 在windows下显示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
这个我还搞不明白为何windows与linux会话字符集为何不同。
更搞不明白的是为何两个数据库实例用同一个系统用户查询的,也就是说环境变量是同样的,但查询结果终端字符集为何会不同?初步分析(固然不必定对,欢迎指正)是两个数据库实例的参数文件不一致引发的,由于alter session>环境变量>注册表>参数文件,也就是说由于环境变量没有设置,但sc与st数据库实例参数文件不一样,可是参数文件在什么地方设还不清楚,有高手欢迎指点!
但基本上问题锁定是由于终端字符集与数据库字符集不一致引发,在用户的环境变量中增长
export NLS_LANG=AMERICAN_AMERICA.UTF8
export LANG=en_US.UTF-8
问题解决
再次查看客户端字符集
select * from nls_instance_parameters 仍是显示
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
但
select * from nls_session_parameters 显示
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
看来只要本次会话字符集正确就没问题了,通过验证确实如此,用
alter session set NLS_LANGUAGE=‘AMERICAN’后本次会话也不会出现乱码的。
)
NSL_LANG包括三个部分(语言_地区.字符集)就是V$NLS_PARAMETERS表中的NLS_LANGUAGE,NLS_TERRITORY,NLS_CHARACTERSET
例如能够在cmd中键入
set nls_lang="Simplified chinese_china.utf8"
set nls_lang="american_america.us7ascii"
set nls_lang="american_america.zhs16gbk"
set nls_lang="Simplified chinese_china.zhs16gbk"
set nls_lang=".utf8"
set nls_lang=".zhs16gbk"
set nls_lang=".us7ascii"
unix下相似, 不过nls_lang要大写NLS_LANG, 在.profile或这.bash_profile(根据你用的shell)里更改NLS_LANG能够长久保持环境变量值.
三、终端字符集
若是数据库字符集和sqlplus的字符集一致, 仍是不能正确显示了, 那极可能就是你的终端应用程序的字符集不支持了. 例如你用bash登录sqlplus, 若是你的bash是个小字符集, 那么就不能正常显示了.linux修改bash的字符集, 能够先键入locale, 看有哪些环境变量, 再用export设置.