为什么stdio.h会打印写入使用文件描述符打开的文件?

时间:2012-03-06 22:26:51

标签: c file unix stdio file-descriptor

我只想写入文件描述符的是输入字符串。但是,它还会写入在fprintf中传递的错误消息。有人能解释为什么它会像这样吗?这个小程序显示了这种行为。

#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;
}

5 个答案:

答案 0 :(得分:3)

write(fd, input, 200)

//...

read(fd, &output, 200)

您正在编写和阅读包含有效数据的数组 - inputoutput都不会接近200字节。那么谁知道文件中会有什么结果(我不确定为什么read()不会导致你的程序崩溃)?

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

听起来像close d stderr或其他什么。不知何故,fdstderr包含相同的整数,因此write(必须失败)和fprintf都使用相同的文件描述符。尝试使用errno或其他内容检查perror的值,然后查看是否有更多信息。

从底线开始,您应该在调试器下运行它并观察fdstderr的值。

答案 3 :(得分:0)

这听起来不像是一个fd问题......而是一个内存错误。请注意,您的格式字符串未被替换,但您获得了实际的格式字符串。您的写入使用block和读取使用&block的事实似乎有点可疑,但很难说是否没有任何上下文。听起来你正在从程序中编写内存,恰好包含程序的字符串。

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

根据添加的代码进行更新:

read()write()不能处理“字符串”,它们会写出你要求的字节数。你的输入是一个字符串文字,它远小于200字节...因为所有字符串文字都可能存储在你程序的同一个通用区域中,这就是你看到其他人在输出中弹出的原因。

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

答案 4 :(得分:0)

输入不是200个字符长。用strlen(输入)替换200

或使用此宏

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

注意,你需要#include&lt; string.h&gt;对于strlen

相关问题