本地化的學習心得

2021-04-12 23:00:22 字數 4048 閱讀 5112

關於本地化的學習心得 閱讀書籍本地化都是通過locale和facet這兩個類來實現的

所有基本的國際化方法都在標準facet中提供。facet提供文化差異的服務和資訊。

名次解釋:國際化:盡量使用通用的做法以及提供多種方法以適應不同語言文化的地區使用。

本地化:利用國際化中提供的方法,改變軟體的行為以適應本地區語言文化的要求。

第一:可以看到,locale已經把facet組合在裡面了,且所有locale物件都有乙個公共的全域性物件global,

目前電腦上這個全域性global基本上就是"c"; 如果使用者沒有指定乙個locale,那麼系統預設使用這個。

第二:所有操作函式都具有const的宣告,這說明locale物件一旦建立,其內容即不可更改。

第三:locate物件的,可以由下面的7個建構函式之一建立,

每個建構函式建立有不同意義的locale 物件,以下就不一一說明了。

locale詳細定義在c++標準裡面的定義(c++標準***2003第二版)可自行查閱,或在locale標頭檔案中察看。   

namespace std ;

}facet 有很多種:

ctype(字元分類),

codecvt(編碼轉換),

collate(校對),

numputct(數字標點資訊),

num_get(數字解析),

num_put(數字格式化),

moneyputct(貨幣標點資訊),

money_get(貨幣解析),

money_put(貨幣格式化),

time_get(時間解析),

time_put(時間格式化)

由此我們可以實現自己的facet就可以自由定製編碼的輸入輸出,從而實現本地化的目標。

我們現在想建立乙個unicode的文字檔案,在c++中需要自己實現乙個facet,

否則就只有使用c函式_wfopen...等等。

如何實現:既實現 codecvt轉換的unicode 的特化的facet版本。

關於facet

facet

ctype(字元分類有:)alpha,digit,crtl,lower,print,punc(標點),space,upper,xdigit(16進製制的0-f),alnum,graph等。

成員函式is():判定是否所屬分類;為方便使用,std重新封裝,變成isspace,isalpha..等形式。

std::tolower,std::toupper也是呼叫的ctype的成員函式tolower,toupper實現的,可找到老家了。

ctype另兩個有用的成員函式是:narrow,widen:用於寬字元和窄字元之間的轉換。

ctype還有乙個串整理collate,用於字元的排序比較。這個我不太關心,我覺得讓他按字符集的排列排序就可以了,呵呵。

codecvt   

下面重點說一下codecvt         

codecvt(編碼轉換),呵呵,我們要用的就是它,它就是在多位元組編碼和寬字元編碼之間進行轉換。

我們的目標就是繼承他,並且實現我們自己的編碼轉換方案,並將它替換到乙個locale物件上的facet上,

通過使用替換後的locale物件 ,達到實現特定編碼集之間進行轉換的目的。

這樣我們有必要了解其每乙個成員函式都是具體做什麼工作的。

其定義是:

templateclass codecvt

模板引數:internt //與內部編碼集相關的字符集,所謂內部編碼, 一般都是記憶體裡整型變數、陣列等。

模板引數:externt //與外部編碼集相關的字符集,所謂外部編碼,指的是外部裝置。檔案、管道,socket  

模板引數:statet  //用於控制內外編碼轉換時狀態的。

codecvt 提供的成員函式分為兩種:一種負責提供編碼轉換資訊的,一種就是提供編碼轉換功能的。 

負責提供編碼轉換資訊有5個:  

always_noconv() //:指出是否需要編碼轉換。

encoding()      //: 指出是否轉換與特定國家相關,外字符集/內字符集的比例是否固定,這個比例是多少?     

length()        //: 確定,對於給出乙個外部字符集的字元,那麼其內部字元的長度是多少。

max_length()    //: 返回乙個內部字元需要外部字元的最大長度。

unshift()       //: 當外部字元與 與內部字元相關時,提供反向操作;

負責提供編碼轉換有2個:

in()           //:執行從外部編碼向內部編碼轉換

out()          //:與in相反。

以前我們已經把對位元組編碼轉化成了unicode編碼,輸出螢幕也正確,可是一旦寫入檔案就會不正確

由此可以猜測到,檔案流在進行寫入操作時,一定是使用了系統預設提供的facet對編碼進行了寬字元到多位元組的編碼轉化。

我們現在要做的,就是使用自己定義的facet,要求檔案流操作不要對編碼進行轉化即可。

因為我們事先已經通過mbstowcs或者multibytetowidechar轉換好了。由此我寫出了如下的facet

//這個

class unifacet:public codecvt

virtual result do_out( mbstate_t& ,

const wchar_t* , const wchar_t* , const wchar_t*,

wchar_t*, wchar_t*, wchar_t& ) const

virtual result do_unshift( mbstate_t&,

wchar_t* , wchar_t* , wchar_t*) const 

virtual int do_length( mbstate_t& , const wchar_t* ,

const wchar_t* , size_t ) const _throw0()

virtual bool do_always_noconv() const _throw0()

virtual int do_max_length() const _throw0() 

virtual int do_encoding() const _throw0()

};仔細看一下,這個facet作了什麼轉化?nothing!,對!這正是我們需要的,告訴呼叫者,什麼都別作,原樣照搬即可。

我們將通過locale 間接使用這個facet

由此我寫出了如下的測試**:驗證了這個推測,不過我現在也是初窺門徑,還有很多沒搞清楚,總算有所得。

完整程式如下://在window下。vs2005下執行通過。

#include

#include

using namespace std;

class unifacet:public codecvt

virtual result do_out( mbstate_t& ,

const wchar_t* , const wchar_t* , const wchar_t*,

wchar_t*, wchar_t*, wchar_t& ) const

virtual result do_unshift( mbstate_t&,

wchar_t* , wchar_t* , wchar_t*) const 

virtual int do_length( mbstate_t& , const wchar_t* ,

const wchar_t* , size_t ) const _throw0()

virtual bool do_always_noconv() const _throw0()

virtual int do_max_length() const _throw0() 

virtual int do_encoding() const _throw0()

};int main()

//unifile<<"123456"

//且只有ascii基本字符集裡才能被正確轉換。

//這個我就沒有再細細追究了。

本地化 日誌本地化

目錄 概要執行時日誌 國際化與本地化 定義你的本地化日誌資訊mymsg enum package org.skzr.logging basename charset utf 8 value org.skzr.logging.msglocallog public enum mymsg 定義國際化檔案o...

Gibberish 本地化外掛程式學習

topic 106389 gibberish是基於rails框架下的乙個語言本地化外掛程式,beast專案使用它進行語言本地化。gibberish 不多,也很容易理解,但是很好地實現了語言本地化的功能,讀了以後感覺有些收穫就寫了這篇文件。一 安裝與配置 在rails專案下,執行 ruby scrip...

Swift 匯出本地化和匯入本地化

一。匯出本地化 1.如下設定,來新增本地化語言 2.匯出檔案 儲存完成後 生成以下兩個檔案 然後用xlifftool 分別開啟以上兩個檔案 在以下顯示 no translation 的地方,新增英文所要替代的語言,如下所示 然後儲存就可以了 二.匯入本地化 1.按如下步驟 2.新增 3新增後出現以下...