2016-10-24 70 views
-4

我想學習C編程語言中的文件I/O概念。我正在使用GNU/Linux(Ubuntu 16.04 LTS)和我的IDE是eclipse 3.8。當我嘗試通過fprintf()方法嘗試寫入文件時,它不會創建任何文件,或者如果該文件甚至已創建,則不會寫入該文件。我試圖通過使用fflush()setbuf(file_pointer, NULL)方法來解決問題,正如建議here但仍然沒有改變。我想我以錯誤的方式寫入文件的地址。fprintf()在ubuntu中不工作

下面是代碼:

#include <stdio.h> 
int main(void){ 
    FILE *file_pointer; 
    file_pointer=fopen("~/.textsfiless/test.txt","w+"); 
    setbuf(file_pointer,NULL); 
    fprintf(file_pointer,"Testing...\n"); 
    fclose(file_pointer); 
    return EXIT_SUCCESS; 
} 

有人能解釋什麼是錯在這裏?

+0

'setbuf(file_pointer,NULL);'必須在文件'fopen'後面完成...... – LPs

+3

爲什麼不檢查'fopen()'的成功? –

+4

檢查'fopen'返回的值,如果文件路徑錯誤,它可能會失敗。 – LPs

回答

3

很可能您致電fopen()失敗。您的程序中沒有任何檢查,以確保fopen甚至可以工作。它可能沒有了,這可能是由於各種各樣的東西,比如你拼寫路徑錯了,錯的文件或進程權限等

要看看究竟發生了什麼,你應該檢查的fopen的返回值:

#include <stdio.h> 
int main(void){ 
    FILE *file_pointer; 
    file_pointer=fopen("~/.textsfiless/test.txt","w+"); 
    if (file_pointer == NULL) { 
     printf("Opening the file failed."); 
     return EXIT_FAILURE; 
    } 
    setbuf(file_pointer,NULL); 
    fprintf(file_pointer,"Testing...\n"); 
    fclose(file_pointer); 
    return EXIT_SUCCESS; 
} 

編輯:由於您的評論,你得到的路徑錯誤是肯定發生了什麼事。如果您從當前目錄執行程序,並且您的文件位於當前目錄中名爲「textfiless」的文件夾中,並且您的文件被稱爲「test.txt」,則可以這樣撥打fopen

file_pointer=fopen("/textsfiless/test.txt","w+"); 
+0

正如我猜,我在問題中提到,似乎我使用的目錄不存在。但我總是使用這樣的目錄,我沒有任何問題。我無法弄清楚這裏的文件目錄是什麼樣的。 –

+0

@ErfanKhalaji我在回答中添加了一段。 – Magisch

+0

我做了你寫的編輯,但仍然沒有改變。 你能把我的問題投票嗎?我真的沒有發現這個問題有什麼問題,但人們投票。 –

4

在Linux上,在~/.textsfiless/test.txt~不是由C庫fopen ...當你在命令行中使用~擴大,它是由擴展您的shell(但不通過使用它的程序,通過啓動殼做一些execve(2) ...)到您的home directory;擴展名爲globbing。閱讀glob(7)。你不可能有一個名爲~的目錄。

你應該閱讀Advanced Linux Programming

所以,你應該檢查是否fopen失敗(這是很可能是它沒有失敗)。如果您想在主目錄中獲取文件,最好使用getenv(3)"HOME"(或者getpwuid(3) & getuid(2) ...)。見environ(7)

也許是更好的代碼可能是:

char*homedir = getenv("HOME"); 
if (!homedir) { perror("getenv HOME"); exit(EXIT_FAILURE); }; 
char pathbuf[512]; /// or perhaps PATH_MAX instead of 512 
snprintf(pathbuf, sizeof(pathbuf), 
      "%s/.textsfiless/test.txt", homedir); 
FILE *file_pointer = fopen(pathbuf, "r"); 
if (!file_pointer) { perror(pathbuf); exit(EXIT_FAILURE); }; 

等。

請注意,您應該檢查大多數C standard library(& POSIX)函數的失敗。 perror(3)功能可用於在stderr上向用戶報告錯誤。

(迂腐,我們甚至應該測試snprintf(3)返回下面sizeof(pathbuf)的長度或使用和測試針對故障asprintf(3)代替;我離開這個測試作爲練習讀者)

更一般地,閱讀documentation您正在使用的每個外部功能。

當心undefined behavior(您的代碼可能有一些,例如fprintfNULL流)。使用所有警告編譯代碼&調試信息(如此gcc -Wall -g)並使用gdb調試器。閱讀What every C programmer should know about undefined behavior.

順便說一句,看看strace(1)並嘗試它在你的原始(錯誤)程序。你會學到很多關於它使用的system calls

+1

我想刪除這個問題,但我不能。 請刪除您的答案。 –

+1

我看不出有任何理由刪除我的答案。它已經不止一次地被提升了,所以它不是那麼糟糕.... –