2012-03-06 146 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