LINUX.ORG.RU

Почему программа продолжает работать, несмотря на EOF


0

2

Есть такой код:

#include <fcntl.h>
#include <unistd.h>
int fd;
int main(int argc, char** argv)
{
	fd=open(argv[1],O_RDONLY);
		int a;
		read(fd,&a,1);
		while(a!=-1){
			write(1,&a,1);
			read(fd,&a,1);
		}
	close(fd);
	return 0;
}
По сути, представляет собой немного переписанный пример из книги Брайана Кернигана и Денниса Ритчи «Язык программирования C», 2- е издание(пример со страницы 30). Почему он продолжает работу после EOF, т.е. заполняет стандартный вывод пустыми символами после достижения конца файла? Как это исправить? Заранее спасибо.

★★

Как-то с трудом верится, что в той книжке могла быть написана подобная чушь. В самом простом варианте будет так (без обработки всех исключительных ситуаций)

    while(read(fd,&a,1) > 0)
        write(1,&a,1);
Советую попробовать почитать man 2 read, там всё прекрасно написано как работает read() и как отличать EOF от ошибки.

mikki ()

Потомучто ты не там берешь результат функции. Посмотри ман.

xcreatepixmap ()
Ответ на: комментарий от mikki

В книжке:

#include<stdio.h>
main()
{
int c;
c=getchar();
while(c!=EOF){
putchar(c);
c=getchar();
}
}
По сути- отличается только тем. что прога в книжке получает инфу со стандартного ввода, а не из файла и тем. что там используется stdio.h , а я избегая его использования заюзал системные вызовы open, read, write, close.

Dorif ★★ ()
int read(handle, buffer,count)

Функция read возвращает число действительно прочитанных байтов, которое может быть меньше, чем count. Возвращаемое значение 0 указывает на попытку чтения конца файла, а 1 - свидетельствует об ошибке.

должно быть правильно

#include <fcntl.h> 
#include <unistd.h> 
int fd; 
int main(int argc, char** argv) 
{ 
   fd=open(argv[1],O_RDONLY); 
      int a; 
      read(fd,&a,1); 
      while(a!=0){ 
         write(1,&a,1); 
         read(fd,&a,1); 
      } 
   close(fd); 
   return 0; 
}
Genuine ★★★ ()
Ответ на: комментарий от mikki

Спасибо за пример кода! Жаль, постоянно забываю доставлять маны от Linux Documentation Project, в стандартных- то информации о функциях языка С нету.(

Dorif ★★ ()
Ответ на: комментарий от Dorif

По сути- отличается только тем. что прога в книжке получает инфу со стандартного ввода, а не из файла и тем. что там используется stdio.h , а я избегая его использования заюзал системные вызовы open, read, write, close.

Важно понимать, что не существует символа EOF. getchar(), как я вижу, вводит в заблуждение. И читать файл по байту с помощью read() не стоит, для этого как раз есть сишные стримы.

mikki ()
Ответ на: комментарий от Dorif

в стандартных- то информации о функциях языка С нету.(

плохо смотришь

Boy_from_Jungle ★★★★ ()
Ответ на: комментарий от mikki

Ну да, в каждой системе он определяется отдельно. Просто Вики ввела в заблуждение, сказав, что обычно это -1. Поправлю.

Dorif ★★ ()
Ответ на: комментарий от Boy_from_Jungle

Стандартные маны Федоры посмотри- там нету. А при установке манов проекта ldp- появляются.

Dorif ★★ ()
Ответ на: комментарий от Genuine
 
#include <fcntl.h>  
#include <unistd.h>  
int fd;  
int main(int argc, char** argv)  
{  
   fd=open(argv[1],O_RDONLY);  
      int a;  
      read(fd,&a,1);  
      while(a!=0){  
         write(1,&a,1);  
         read(fd,&a,1);  
      }  
   close(fd);  
   return 0;  
}

А если в файле есть нули :)?

Bragin ()
Ответ на: комментарий от Genuine

Функция read возвращает число действительно прочитанных байтов, которое может быть меньше, чем count. Возвращаемое значение 0 указывает на попытку чтения конца файла, а 1 - свидетельствует об ошибке.

Так может всё-таки с нулём нужно сравнивать результат read(), а не вычитанное ей значение? Что-то типа:

#include <fcntl.h>
#include <unistd.h>
int fd;
int main(int argc, char** argv)
{
   fd=open(argv[1],O_RDONLY);
   int a;
   char c;
   a = read(fd,&c,1);
   while(a>0){
      write(1,&c,1);
      a = read(fd,&c,1);
   }
   close(fd);
   return 0; 
}

Ну и об ошибке свидетельствует -1 , а не 1.

Laz ★★★★ ()
Ответ на: комментарий от Laz

>Ну и об ошибке свидетельствует -1 , а не 1.

Которую тоже надо проверять в коде:)

anonymous ()

Я вижу море говнокода от Dorif и Genuine в этом треде.

anonymous ()
Ответ на: комментарий от anonymous

советую им почитать man 2 read и man 3 getc до просветления.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.