簡體   English   中英

從C語言的輸入文件中讀取CJK字符

[英]Reading CJK characters from an input file in C

我有一個文本文件,可以包含中文,日文,韓文(CJK)和英文字符的混合。 我必須驗證文件中的英文字符。 僅當行以'$'字符開頭時,該文件才能包含CJK字符,該字符代表我的文本文件中的注釋。 通過網絡搜索,我發現可以使用fgetws()wchar_t類型讀取寬字符。

Q1)但我想知道CJK字符如何存儲在我的文本文件中-字節順序等

Q2)如何循環瀏覽CJK字符。 由於Unicode字符可以有1到6個字節,所以我不能使用i ++。

任何幫助,將不勝感激。

非常感謝。

您需要將UTF-8文件讀取為一系列UTF-32代碼點。 例如:

std::shared_ptr<FILE> f(fopen(filename, "r"), fclose);
uint32_t c = 0;
while (utf8_read(f.get(), c))
{
    if (is_english_char(c))
        ...
    else if (is_cjk_char(c))
        ...
    else
        ...
}

其中utf8_read具有簽名:

bool utf8_read(FILE *f, uint32_t &c);

現在,根據第一個字節的值, utf8_read可以讀取1-4個字節。 請參閱http://en.wikipedia.org/wiki/UTF-8 (谷歌)以獲取算法或使用已經可用的庫函數。

使用UTF-32代碼點,您現在可以檢查范圍。 對於英語,您可以檢查它是否為ASCII( c < 0x7F )還是Latin字符(包括對從法語導入的單詞的重音字符的支持)。 您可能還希望排除不可打印的控制字符(例如0x01 )。

對於Latin和/或CJK字符檢查,您可以檢查字符是否在給定的代碼塊中(有關代碼點范圍,請參見http://www.unicode.org/Public/UNIDATA/Blocks.txt )。 這是最簡單的方法。

如果您使用的是具有Unicode支持且具有編寫腳本檢測功能的庫(例如glib庫),則可以使用腳本類型來檢測字符。 或者,您可以從http://www.unicode.org/Public/UNIDATA/Scripts.txt獲取數據:

Name     : Code      : Language(s)
=========:===========:========================================================
Common   : Zyyy      : general punctuation / symbol characters
Latin    : Latn      : Latin languages (English, German, French, Spanish, ...)
Han      : Hans/Hant : Chinese characters (Chinese, Japanese)
Hiragana : Hira      : Japanese
Katakana : Kana      : Japanese
Hangul   : Hang      : Korean

注意:腳本代碼來自http://www.iana.org/assignments/language-subtag-registryType == 'script' )。

您需要了解UTF-8並使用一些UTF8處理庫(或自己編寫代碼)。 僅供參考, Glib (來自GTK)具有UTF-8處理功能,能夠處理可變長度的UTF-8字符和字符串。 還有其他UTF-8庫,例如iconv-在GNU libc內-以及ICU等。

UTF-8確實定義了多字節UTF8字符(例如中文)的字節順序和內容。

我正在粘貼示例程序來說明wchar_t處理。 希望它可以幫助某人。

#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#define BUFLEN 1024
int main() {
  wchar_t *wmessage=L"Lets- beginめん(下) 震災後、保存-食で-腳光-(経済ナビゲーター)-lets- end";
  wchar_t warray[BUFLEN + 1];
  wchar_t a = L'z';
  int i=0;
  FILE *fp;
  wchar_t *token = L"-";
  wchar_t *state;
  wchar_t *ptr;
  setlocale(LC_ALL, "");
  /* FIle in current dirrctory containing CJK chars */
  fp = fopen("input", "r");
  if (fp == NULL) {
      printf("%s\n", "Cannot open file!!!");
      return (-1);
  }
  fgetws(warray, BUFLEN, fp);
  wprintf(L"\n *********************START reading from file*******************************\n");
  wprintf(L"%ls\n",warray);
  wprintf(L"\n*********************END reading from file*******************************\n");
  fclose(fp);
  wprintf(L"printing character %lc = <0x%x>\n", a, a);
  wprintf(L"\n*********************START Checking string for Japanese*******************************\n");
  for(i=0;wmessage[i] != '\0';i++) {
      if (wmessage[i] > 0x7F) {
          wprintf(L"\n This is non-ASCII <0x%x> <%lc>", wmessage[i],  wmessage[i]);
      } else {
          wprintf(L"\n This is ASCII <0x%x> <%lc>", wmessage[i],  wmessage[i]);
      }
  }
  wprintf(L"\n*********************END Checking string for Japanese*******************************\n");
  wprintf(L"\n*********************START Tokenizing******************************\n");
  state = wcstok(warray, token, &ptr);
  while (state != NULL) {
      wprintf(L"\n %ls", state);
      state = wcstok(NULL, token, &ptr);
  }
  wprintf(L"\n*********************END Tokenizing******************************\n");
  return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM