簡體   English   中英

讀取不存在的文件

[英]reading a file that doesn't exist

我有一個小程序,使用系統調用打印文件的內容 - 讀取。

unsigned char buffer[8];
size_t offset=0;
size_t bytes_read;

int i;

int fd = open(argv[1], O_RDONLY);

do{
    bytes_read = read(fd, buffer, sizeof(buffer));
    printf("0x%06x : ", offset);

    for(i=0; i<bytes_read; ++i)
    {
        printf("%c ", buffer[i]);
    }
    printf("\n");
    offset = offset + bytes_read;
}while(bytes_read == sizeof(buffer));

現在,在運行時,我給出了一個不存在的文件名。 它打印出一些與環境變量混合的數據和最后的分段錯誤。

這怎么可能? 什么是程序打印?

謝謝,約翰

它打印垃圾是因為fd總是被設置為-1,這對於傳遞read來說並不是一件好事,因為它會反過來除了返回-1之外什么都不做。 它會讓你的緩沖區不受影響,這意味着當你開始時它會保留你在那里的垃圾。

您可以將整個do循環放在以下內容中:

if (fd == -1) {
    printf ("error here");
} else {
    // do loop here
}

read返回-1因為fd無效,你將它存儲在bytes_read中,它是size_t類型的無符號,所以你的循環打印(size_t)-1個字符,這是一個非常大的數字,遠大於緩沖區的大小。 因此,您打印了大部分地址空間,然后在最終到達終點並訪問無效地址時獲得段錯誤。

正如其他人所提到的(沒有回答你的實際問題),你應該檢查打開錯誤的結果。 例如,

int fd = open(argv[1], O_RDONLY);
if( fd < 0 ){
    fprintf(stderr, "error opening %s: %s\n", argv[1], strerror(errno));
    exit(1);
}

需要注意的是:如果您在調用strerror之前執行另一個系統調用或調用任何可能進行系統調用的例程(例如printf),則必須保存errno,然后將保存的副本傳遞給strerror。

關於你的計划的另一個說明

while(bytes_read == sizeof(buffer))

這不是一個好的測試,因為讀取的回報可能低於您要求的數量。 您的循環應該繼續,直到讀取返回<= 0。

在使用之前,您應該檢查open返回的文件描述符是否有效。 根據這些文檔 ,您應該獲得有效文件的非否定響應。 從無效的描述符中讀取可能是您的問題的根源。

成功完成后,open函數將打開文件並返回表示文件描述符的非負整數。 否則,返回-1並設置errno以指示錯誤。 所以請在進入循環之前檢查fd以執行讀取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM