撰寫 DBCS 相容應用程式的資訊: 秘訣

文章翻譯 文章翻譯
文章編號: 75439 - 檢視此文章適用的產品。
本文已封存。本文係以「現狀」提供且不會再更新。
3.00 3.10 WINDOWS kbprg
全部展開 | 全部摺疊

結論

使用一個雙位元組字元集 (DBCS) 的系統中的字串作業會從單一位元組字元集系統略微不同。 本文提供指導方針來減少連接埠寫入為單一位元組系統 DBCS 系統的應用程式的必要工作。

其他相關資訊

雙位元組字元組中的某些字元需要兩個位元組,而有些需要只有一個位元組。語言驅動程式可以分辨這兩種類型的字元來指定某些字元作為前置位元組。前導位元組將後面跟著另一個位元組 (一個 「 尾端位元組 」) 建立雙位元組一個雙位元組字元 (字元)。前置位元組組是為每種語言不同。前置位元組永遠保證要擴充的字元 ; 沒有 7 位元 ASCII 字元可以是前導位元組。機尾位元組可能 NULL 位元組以外的任何位元組。字串結尾一定被定義為第一個 NULL 位元組字串中。前置位元組是合法的尾巴位元組 ; 告訴是否一個位元組做為前導位元組唯一的方法,就是從內容。

「 Windows 軟體開發套件 (SDK) 3.0 版包含兩個函式的字串可能包含 DBCs 間移動: AnsiNext()AnsiPrev()AnsiPrev() 函式是時間昂貴的呼叫,因為它必須從一開始決定前一字元開始執行透過字串。最好搜尋字元開頭,而不是一個字串的結尾。

Windows SDK 3.1 版包括 IsDBCSLeadByte() 函式傳回 TRUE 時,才將位元組可能是前導位元組。因為這個函式會採用一個 char 參數,它無法報告之位元組如果 IS 前導位元組 (如果要執行這項操作,需要內容)。

若要讓非 DBCS 的程式碼執行儘快,原始程式檔可能僅供 DBCS 的程式碼周圍使用"# ifdef DBCS",並編譯兩個版本的物件 (OBJ) 檔案。例如:
   #ifdef DBCS
     for (pszTemp = szString; *pszTemp; pszTemp = AnsiNext(pszTemp))
   #else
     for (pszTemp = szString; *pszTemp; ++pszTemp)
   #endif

   ...
				
若要讓程式碼更容易閱讀的應用程式可以定義 AnsiNext()] 和 [AnsiPrev() 函數的巨集如果 DBCS 未定義:
   #ifndef DBCS

   #define AnsiNext(x) ((x)+1)
   #define AnsiPrev(y, x) ((x)-1)

   #ifdef WIN31

   #define IsDBCSLeadByte(x) (FALSE)

   #endif

   #endif
				
就地這些定義,與所有的程式碼可以寫入 DBCS 的。請注意 AnsiNext() 函式不會去超過字串的結尾,而且巨集將會時,將不 AnsiPrev() 函式變成過去的一個字串的開頭。在另外"y"參數 AnsiPrev() 巨集中會忽略,因為一些程式碼會提供不同的結果,當編譯使用和不使用 DBCS 定義。下列程式碼就是這種現象的範例:
   pszEnd = AnsiPrev(++pszStart, pszEnd);
				
下列的程式碼示範如何尋找 [完整路徑名稱中的 [檔案名稱的位移:
   LPSTR GetFilePtr(LPSTR lpszFullPath)
   {

    LPSTR lpszFileName;

    for (lpszFileName = lpszFullPath; *lpszFullPath;
               lpszFullPath = AnsiNext(lpszFullPath))
        if (*lpszFullPath == ':' || *lpszFullPath == '\\')
            lpszFileName = lpszFullPath + 1;

    return lpszFileName;

   }
				
請注意,': '和' \ \ ' 保證不為前置位元組。從字串,而不是避免使用 AnsiPrev() 函式結尾的開頭,啟動搜尋。

下列程式碼會示範到有限的大小緩衝區的字串複本。請注意,它可確保字串不會結束與前導位元組。
   int StrCpyN(LPSTR lpszDst, LPSTR lpszSrc, unsigned int wLen)

   {

    LPSTR lpEnd;
    char cTemp;

    // account for the terminating NULL
    --wLen;

    for (lpEnd = lpszSrc; *lpEnd && (lpEnd - lpszSrc) < wLen;
               lpEnd = AnsiNext(lpEnd))
        ;  // scan to the end of string, or wLen bytes

    // The following can happen only if lpszSrc[wLen-1] is a lead
    // byte, in which case do not include the previous DBC in the copy.
    if (lpEnd - lpszSrc > wLen)
        lpEnd -= 2;

    // Terminate the source string and call lstrcpy.
    cTemp = *lpEnd;
    *lpEnd = '\0';
    lstrcpy(lpszDst, lpszSrc);
    *lpEnd = cTemp;

   }
				

屬性

文章編號: 75439 - 上次校閱: 2013年10月7日 - 版次: 1.1
這篇文章中的資訊適用於:
  • Microsoft Windows Software Development Kit 3.1
關鍵字:?
kbnosurvey kbarchive kbmt kb16bitonly kbinfo KB75439 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:75439
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com