2014-08-30 110 views
-3

我有一個基於用戶輸入的C中的char *字符串。從這個字符串中,我想選擇一個從第一個位置開始的子字符串,以便在固定寬度的終端上生成的子字符串是n列寬。C:從多字節字符串中選擇一個子字符串,n列寬

從來沒有在過去使用過非ASCII字符,我完全喪失瞭如何解決這個問題,甚至是開始。一些初步的搜索建議使用libiconv,但似乎沒有幫助。我也嘗試過使用wchar.h,支持廣泛的角色,但我不確定這是正確的選擇。

編輯:這是我試圖在第一次嘗試:

static int 
count_n_cols (const char *mbs, char *mbf, const int n) 
{ 
    wchar_t wc; 
    int  bytes; 
    int  remaining = strlen(mbs); 
    int  cols = 0; 
    int  wccols; 

    while (*mbs != '\0' && cols <= n) 
    { 
     bytes = mbtowc (&wc, mbs, remaining); 
     assert (bytes != 0); /* Only happens when *mbs == '\0' */ 
     if (bytes == -1) 
     { 
      /* Invalid sequence. We'll just have to fudge it. */ 
      return cols + remaining; 
     } 
     mbs += bytes; 
     remaining -= bytes; 
     wccols = wcwidth(wc); 
     *mbf += wc; 
     cols += (wccols == -1? 1 : wccols); 
    } 
    return cols; 
} 
+0

添加了我試圖寫入的函數。我不確定這是否是繼續前進的最佳方式。 – darnir 2014-08-30 03:56:51

+1

你的代碼有什麼問題?乍一看它看起來不錯。 – 2014-08-30 04:04:28

回答

0

如果我理解你的問題正確的話,你要計算的UTF-8序列的數量而不做任何轉換執行你的子。您可以通過讀取序列的第一個字節來計算與每個'列'相對應的字節數,如utf-8標準所指定的。這裏是一些示例代碼,基於你的示例功能和Wikipedia's UTF-8 description

static int count_n_cols (const char *mbs, char *mbf, const int n) 
{ 
    int bytes; 
    int length = strlen(mbs); 
    int cols = 0; 

    for (bytes = 0; bytes < length; bytes++) 
    { 
     if (mbs[bytes] == '\0' || cols >= n) 
      break; 
     else if ((mbs[bytes] & 0x80) == 0) // the first bit is 0 
     { 
      cols++; 
     } 
     else if ((mbs[bytes] & 0xE0) == 0xC0) //the first 3 bits are 110 
     { 
      //two bytes in utf8 sequence 
      cols++; 
      bytes++; 
     } 
     else if ((mbs[bytes] & 0xF0) == 0xE0) //the first 4 bits are 1110 
     { 
      //three bytes in utf8 sequence 
      cols++; 
      bytes += 2; 
     else if ((mbs[bytes] & 0xF8) == 0xF0) //the first 5 bits are 11110 
     { 
      //four bytes in utf8 sequence 
      cols++; 
      bytes += 3; 
     } 
     else 
     { 
      putc(mbs[bytes],stdout); 
      printf(" non_ascii %d\n", mbs[bytes] & 0x80); 
     } 
    } 
    strncpy(mbf, mbs, bytes); 
    mbf[bytes] = '\0'; 
    return cols; 
} 
相關問題