2016-10-24 44 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

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