![](/img/trans.png)
[英]***Reading from file in C*** using fscanf, Scanning and printing a char that doesn't exist in .txt file
[英]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.