2012-03-06 149 views
0

我只想写入文件描述符的是输入字符串。但是,它也会写入在fprintf中传递的错误消息。有人能解释为什么它的行为如此吗?这个小程序显示了行为。为什么stdio.h会打印写入用文件描述符打开的文件?

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdio.h> 

int main(void) 
{ 
    int fd; 
    mode_t mode = S_IRUSR | S_IWUSR; 
    char *filename = "file.txt"; 
    char *input = "hello world"; 
    char output[20]; 

    // create and close 
    if((fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, mode)) == -1) 
    { 
     fprintf(stderr, "Error.\n"); 
     return -1; 
    } 
    close(fd); 

    // just open 
    if((fd = open(filename, O_RDWR, mode)) == -1) 
    { 
     fprintf(stderr, "Error.\n"); 
     return -1; 
    } 

    if(write(fd, input, 200) == -1) 
    { 
     fprintf(stderr, "Error.\n"); 
     return -1; 
    } 

    // move back to beginning 
    if(lseek(fd, 0, SEEK_SET) == -1) 
    { 
     return -1; 
    } 

    if(read(fd, &output, 200) == -1) 
    { 
     fprintf(stderr, "Error.\n"); 
     return -1; 
    } 

    printf("%s\n", output); 

    return 0; 
} 
+1

你没有向我们展示足够的程序来回答你的问题。请提供一个完整的例子。 – 2012-03-06 22:30:01

+0

“即使达到它”是什么意思?即使您的诊断程序正在打印,我似乎也得到了文件输出似乎正在发生的要点。我怀疑你认为发生的事情并不是真的发生,你只是以某种方式迷惑自己。请注意,您的open()调用不会截断文件。你是否检查open()成功,甚至?也许你并没有真的打开文件,文件描述符实际上是不好的。但是当你看文件时,你正在查看正确的文件,并且数据在那里。当您执行ls -l时,文件上的时间戳是什么? – Kaz 2012-03-06 22:34:01

+0

我只想写入文件描述符的是块中的内容。但是,当我在写入文件后打开文件时,它包含块中的消息以及所有fprintf消息,例如无法写入。\ n – Kobi 2012-03-06 22:45:54

回答

3
write(fd, input, 200) 

//... 

read(fd, &output, 200) 

你写作和阅读以及经过包含有效数据的阵列 - inputoutput都不会接近200字节。所以谁知道最终会在文件中发生什么(我不确定为什么read()不会导致程序崩溃)?

0

我会赌钱'fd'正在被宣布或范围奇怪。 UNIX中的文件描述符只是一个介于0和某个最大值之间的整数(曾经是20,现在它更大),它是表中的索引。 STDIN==0STDOUT==1STDERR==2

如果你看到你所描述的行为,不知何故fd是== 2

+0

应该如何声明fd。目前,它已被宣布,但尚未设置,直到打开被调用。然后,如果它== -1,我错误,否则返回3. – Kobi 2012-03-06 22:45:02

0

这听起来像你close d stderr什么的。不知何故,fdstderr包含相同的整数,因此您的write(必须失败)和fprintf使用相同的文件描述符。尝试检查errno的值,也许使用perror或其他东西,看看有没有更多的信息。底线,您应该在调试器下运行它并观察fdstderr的值。

+0

从open返回的fd是3,这是正确的,因为我正在写入另一个文件。不是stderr,它是2. – Kobi 2012-03-06 22:52:25

0

这听起来不像是一个fd问题,而是一个内存错误。注意你的格式字符串没有被替换,但是你得到了实际的格式字符串。你写的使用block和阅读使用&block的事实似乎有点可疑,尽管很难说如果没有任何背景的话。这听起来像你正在从你的程序写内存,恰好包含你程序的字符串。

我建议使用valgrind运行你的程序。

UPDATE基础上添加代码:

read()write()不上“弦”的工作,当你问他们会写的字节数。你的输入是一个字符串文字,它比200字节小很多......因为所有字符串文字都可能存储在程序中的相同区域,这就是为什么你会看到其他人弹出输出。

还有一些其他问题 - 您的输出缓冲区不够大,无法处理您请求的read(),并且您可能希望在写入和读取之间使用lseek()以便能够再次读取数据。

+0

我在原始文章中添加了一个示例程序。我没有使用相同的变量进行读写,这只是一个例子。对于那个很抱歉。 – Kobi 2012-03-06 23:00:20

0

输入不是200个字符长。与strlen的(输入)更换200

或者使用这个宏

#define write1(s) write(1, s, strlen(s)) 

注意,你需要#包括< string.h>的函数strlen

+0

那将是。 :) – Kaz 2012-03-07 02:22:28

+0

@Kaz - 修好了,谢谢 – technosaurus 2012-03-07 02:40:03