EOF checking the below

Hi,

I am practicing exercise programs with System calls.

Exercise Question: write a pogram to accept a filename from the user. The program should write ecery fifth byte of the file to the standard output.

My Program :

# include <stdio.h>
# include <fcntl.h>
# include <error.h>

main()
{
int fd,first_offset=5,move_offset=0,x=1;
char a,name[20];
scanf("%s",name);

fd = open\(name,O_RDONLY,0755\);
printf\("fd is %d",fd\);

if\(fd==-1\)
\{
 printf\("error"\);
 exit\(1\);
\}

while\(x&lt;5\)
\{
    move\_offset=move\_offset\+first_offset;
    lseek\(fd,move_offset-1,0\);
    read\(fd,name,sizeof\(name\)\);
    write\(1,name,1\);
    x\+\+;
\}

}

Output:
[ramki@lindesk3 sysint_ex]$ cc ex1.c -o ex1
[ramki@lindesk3 sysint_ex]$ ./ex1
./test
FIVEfd is 3

The file "Test" content:
abcdFfghiIklmnVpqrsE

My Question Now:

  1. in the program, I used a While loop with an varaible "X" and comparing it to random no of my choice 5 . Instead I want to check the EOF condition in the whilepart. How to check that.
    If we are using file pointer and fopen fn, we can use while(feof(fp)==0). But here we used syatem calls and I don know how to check the condition here.

  2. In te program output, I found "FIVE" before printing the filedescriptor number. But as per my program flow, fd should be printed first and then the output "FIVE".

3.Is there any othet way of writing the program more simple and precise, especially using piointer for getting the name of the file, instaed of using Array.

Please Help...

Thanks,
Ramkrix

#include <stdio.h>

main(int argc, char *argv[])
{
    char *infile;
    FILE *stream;

    infile = argv[1];
    stream = fopen(infile, "r");
}

...now you can use the stream status functions like feof or ferror.

Thanks for your reply shamrock..

Is tis the way, I need to include the condition in while loop:

while(feof(stream)==0)

One more question to you: instead of using command line args and C library fns can we check this by having the program absolute system calls..

Thanks in advance,
Ramkrix

You can use "absolute system calls" instead of standard C library routines like fopen() and you can avoid passing the input filename as a command line argument at the expense of hardcoding the input filename in the open() system call.

The system call approach is better for reading 5 bytes at a time from the input file and printing the fifth byte to standard output. This method is preferred over incrementing a counter and repeatedly testing if x < 5 or checking for EOF using the feof() standard lib function.

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

main(int argc, char *argv[])
{
    int fd;
    char name[5];

    fd = open("/path/to/input/file", O_RDONLY);

    while (read(fd, (void *) name, (size_t) 5) == 5)
        printf("the fifth byte is %c\n", name[4]);
}

Once Again thanks for the useful info Shamrock.

let me ask you the last ques from your reply:
while (read(fd, (void *) name, (size_t) 5) == 5)

The "(size_t)5", what does it mean and will it do?Bcoz i read from a book that we need to give the sizeof() operator at the end. Also you are comaparing it to value "==5"? I could not understand here.

The below one is what I coded in my program: read(fd,name,sizeof(name));

Was mine a right one?:confused:

sizeof(name) is 20 since you defined name as an array of 20 characters i.e. char name[20]. Therefore your program tries to read 20 bytes at a time - with no error checking.

Here the program tries to read 5 bytes and checks that it has actally read 5 bytes. size_t is defined by ISO C for use in representing size information and is very useful whien code portability across different architectures and programming models is desirable. It is required to be an unsigned integral type. Typically it is an int or long.

Thanks fmurphy for your reply.

if I have a structure defined at the beginning in another prgm instaed of an char array name[20],can I use like this?

struct bio {
char name[20];
int age;
float salary;
}

main()
{
struct bio mydata;
--------
--------
--------

read(fd, &mydata, (size_t) ))

}
How can we use the size_t with structure?

Thanks in Advance..

Ramkrix

You need to do something like the following

read(fd, &mydata, (size_t)mydata )

fpmurphy's post clearly says that size_t is a typedef for an unsigned long. Declare a variable of that type as a structure member before using it in the read() call. The (size_t) is the C lang notation for a typecast used when converting from one type to another. Wrap code tags around your program listings.

struct bio
{
     char name[20];
     int age;
     float salary;
     size_t num_of_bytes_read;
}

main()
{
    read(fd, &mydata, num_of_bytes_read)
}

Thanks fmurphy for your kind xplanation.

Regards,
Ramkrix

Thank you Shamrock

Regards,
Ramkrix