2012-08-08 40 views
2

當我的程序試圖stat()包含特定的UTF-8字符的文件時,stat()函數返回一個錯誤。例如,我可以用vi打開文件/tmp/surgateDlpMgQure/Özkul Gazete,但將同一個文件傳遞給stat()會產生錯誤。系統區域設置爲:stat函數:沒有這樣的文件或目錄錯誤

LANG =的en_US.UTF-8

LC_CTYPE = 「的en_US.UTF-8」

LC_COLLATE = C

LC_TIME =「的en_US.UTF-8 「

LC_NUMERIC =」 的en_US.UTF-8"

LC_MONETARY = 「的en_US.UTF-8」

LC_MESSAGES = 「是en_US.UTF-8」

LC_ALL =

我應該做的,以東西stat()瞭解UTF-8字符?

下面是代碼:

int main() 
{ 
    struct stat s; 
    if (stat("/tmp/surgateDlpMgQure/Özkul Gazete", &s) == -1) 
      perror("stat"); 


    switch (s.st_mode & S_IFMT) { 
      case S_IFBLK: printf("block device\n");   break; 
      case S_IFCHR: printf("character device\n");  break; 
      case S_IFDIR: printf("directory\n");    break; 
      case S_IFIFO: printf("FIFO/pipe\n");    break; 
      case S_IFLNK: printf("symlink\n");     break; 
      case S_IFREG: printf("regular file\n");   break; 
      case S_IFSOCK: printf("socket\n");     break; 
      default:  printf("unknown?\n");    break; 
    } 

return 0; 
} 
+1

你可以發佈代碼...所以我們可以知道你如何使用stat()? – 2012-08-08 08:18:09

+0

好的我編輯的問題。 – iyasar 2012-08-08 08:27:20

回答

0

的問題可能是,文件名的編碼不 與您在程序中內部使用的編碼相同。這裏的關鍵 問題是誰創建了這個文件(並給出了它的名字),以及 代碼中的字符串來自哪裏。大多數Unix與 有關的編碼是不可知的,只要幾個特殊字符,如 '/',具有預期的編碼。因此,獨立於您的 當前語言環境,文件名可以是Latin-1,Latin-5(只是猜測, 但名稱看起來像土耳其語)或UTF-8。在Unix中幾乎沒有關心, 但必須確保在你的程序中,你使用相同的編碼 作爲用於創建該文件,或名稱不匹配。 (在實踐中, 我發現最簡單的政策,是在 文件名中的字符限制在一個很小的一套:在ASCII字母數字字符,數字, '_',並可能'-'

如果你不確定磁盤上文件名的實際編碼, ,您可以使用ls | od -t x1 -tc找出其中 字節的實際值。如果你的Ö是0xD6,那麼編碼是Latin-1 或Latin-5(它可能不會產生太大的差別),並且 你必須確保你通過的文件名爲stat(或open,或任何其他帶有文件名的函數)編碼在其中一個編碼中。相反,如果您有兩個字節序列0xC3,0x96, ,則文件名爲UTF-8。

如果你想支持ASCII子集之外的字符,然後 我強烈建議你確保所有在UTF-8編碼 。假設您可以—編碼將由 決定創建該文件的程序,如果它不是您的程序(或者如果 您從另一個系統接收該文件),則可能無法對其執行任何操作。在最壞的情況下,您甚至可能需要 使用opendirreaddir以某種匹配算法找到 實際文件名(無論編碼),並使用它。

-1

簡單的方法來破解它周圍:

使用Unicode字符的轉義表示:

"/tmp/surgateDlpMgQure/\x00\xF6zkul Gazete"

我沒有測試,但它會起作用。雖然它不是去與unicode字符串的C.

古怪足夠的方式,你的代碼工作我的系統上,但不是我:)

+2

它不可能使用你給出的字符串,因爲'\ 00'是一個空字符,它將被'stat'視爲字符串的結尾。 – 2012-08-08 08:41:28

0

我覺得有問題,是由於在該文件名的命名空間......

你可以嘗試改變這種文件名沒有空間

Özkul Gazete -> Özkul_Gazete 

在Linux上通常我不在文件名中使用空格或目錄名稱

相關問題