最近,學習又從新開始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設置.