2017-10-20 86 views
0

當我嘗試使用open()函數在LINUX中創建文件時,出現錯誤'-1'包含擴展字符(例如:Björk.txt)。這裏,文件包含特殊字符ö(ASCII 148)在Linux中使用擴展字符(128-255)的open()函數返回-1錯誤

我使用下面的代碼:

char* szUnixPath

/home/user188/Output/Björk.txt

open(szUnixPath, locStyle, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 

我總是得到-1錯誤,並且NO FILE被創建。

當操作系統遇到ASCII 148時,會引發錯誤。如果我使用波浪號〜(ASCII 126,例如:北京〜rk.txt)

功能相同工作完全正常或低於ASCII值128

任何其它字符可有人解釋爲什麼我得到的 - 只有在特殊字符範圍在128-255之間的文件名時出現1錯誤?

+2

不確定,但您可能需要使用UTF-8編碼。 –

+0

我試過UTF-8編碼。沒有工作!那麼,我使用CP437 – adam

+0

你如何輸入文件的名稱?從控制檯或GUI輸入?在源代碼中進行硬編碼?您確定您傳遞給'open'的文件名的編碼與文件系統爲其文件名使用的編碼相同嗎? –

回答

1

我推薦試試看看這個名字包含什麼字節。

創建一個目錄中的文件,然後運行下面的簡單的C程序:

#include <dirent.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    /* Open directory */ 
    DIR * currdir = opendir("."); 

    /* Iterate over files */ 
    struct dirent * directory_entry = NULL; 
    while (NULL != (directory_entry = readdir(currdir))) 
    { 
     char * entry_name = directory_entry->d_name; 
     printf("Directory entry: %s\n", entry_name); 
     printf("Name bytes (len: %d):\n", strlen(entry_name)); 
     for (size_t i = 0; i < strlen(entry_name); ++i) 
     { 
      printf("\tname[%d] = %d\n", i, entry_name[i]); 
     } 
    } 

    return 0; 
} 

我們所用的輸出很容易地看到「比約克」的長度爲6字節。我們可以看到這些字節值:

Directory entry: Björk 
Name bytes (len: 6): 
    name[0] = 66 
    name[1] = 106 
    name[2] = -61 
    name[3] = -74 
    name[4] = 114 
    name[5] = 107 
+0

你是對的。我得到相同的輸出,但我只是好奇地知道如何特殊字符ö值是負數-61和-74 – adam

+0

@adam:這是ö的UTF-8編碼,錯誤地打印爲有符號值。 (正常的演示文稿應該是十六進制的C3 B6,這是這個答案中顯示的整數的二進制補碼錶示。) – rici

+0

在我的代碼中,當使用輸出字符集UTF8時,我得到的輸出爲'Bj \ 224rk.txt'。有人可以告訴我哪裏錯了嗎?我已經將字符編碼設置爲UTF8 – adam

0

Linux中的文件名通常以UTF-8而不是CP437來指定。 open失敗,因爲您傳遞的文件名與操作系統中的文件名不匹配。

嘗試打開此文件:/home/user188/Output/Bj\xc3\xb6rk.txt。這是以UTF-8編碼爲兩個字節的特殊字符。

+0

「*通常在UTF-8中指定*」< - 不是真的,儘管是普通的......它們通常只是不透明的字節序列,使用創建它們的任何編碼。 –

+0

@felix:取決於文件系統,不是? – rici

+0

@rici一些文件系統可以選擇轉換文件名編碼,但通常情況並非如此。用戶空間API僅將名稱視爲字節序列。 –