• C

Open/Read/Write files

Hi folks,

I am new to C and I am totally confused by various open/read/write files calls.

for example, to open a file, it seems I can do open & fopen, to get some input from a file, I can do fgetc, fread, fgets, etc.

Could you please explain open/read/write in details? I'd like to know the most popular way to do open/read/write in C.

Let's suppose I need to read from a file (does text or binary matter?), with a buffer size of 4 bytes, print the content of the buffer byte by byte,

i.e I read 16-bit info and display (decimal) value represented by each byte (#1-#4, ... ... #13-#16 bits), say, I read 0000 0000  0000 002A, it will print that the 1st/2nd/3rd quater of the buffer is 0, and the last is 42 (HEX 2A=DEC 42) )in monitor (in string, which is human readable, and in HEX, respectively),

then write values just read into another file.

Thanks

Pls highlight key points to

1) open file (construct a file pointer or file descriptor? why?)
2) read in buffer
3) read & get byte's value in the buffer (a buffer has 4 bytes), and represent it in HEX, OCX, DEC, or in string
4) write to file
LVL 1
tiger0516Asked:
Who is Participating?
 
sunnycoderCommented:
Here are some details ....

open, read, and write are used for low level I/O ... here you have to deal with the bytes yourself ... Also, this form of I/O is unbuffered ... e.g. as soon as you call write(), it would all be written to the file on the disk .... On the other hand fread() etc are typically buffered .. they are written to a buffer and fluhsed to the disk later ...

Given your requirements
>Let's suppose I need to read from a file (does text or binary matter?),
>with a buffer size of 4 bytes, print the content of the buffer byte by byte,
Yes, text or binary matters ... that would determine how you read your file ... A binary file, it may contain byte sequence(s) which would normally terminate reading of a text file ... In the same vein, text file may have certain modifications e.g. windows newline consists of CRLF sequence which would disturb the contents of a binary file if it is treated as text. So type of file is important and it can make or break your programs ...

Here you are seeking to read and write bytes ... since you do not need any form of formatting on your I?O you can choose to use open() followed by read() write() or you can use fopen() followed by fread() and fwrite() ... Typically (but not always) we would prefer to use FILE * interface since it is more convenient to program with. Internally FILE * would map to fd

FILE * fptr  = fopen (filename, "rb");
As I said before b flag is ignored on the *nix platforms. make sure you check the return values to make your program more robust. I am omitting checks for ease of reading.

Once you have the file open, you can read 4 bytes from it
fread(buffer,1,4,fptr);

To display them char by char, use a loop such as
for (i=0; i<4; i++)
     printf("%c ",buffer[i]);

>So if I want to speak with Bytes, I'd better to use fd?
As I had shown above, you can still use fread and fwrite to treat your input as a sequence of bytes ...you could have used low level I/O too but typically that is used only when required .. e.g. when you are working with pipe() or an fcntl() or you need to dup() it ... All low level calls.

Cheers!
sunnycoder
0
 
sunnycoderCommented:
Hi tiger0516,

> 1) open file (construct a file pointer or file descriptor? why?)
FILE * is at a higher level that fd ... Internally it would map to an fd but using a FILE * you can read in formatted input and write formatted output .. using fd, you work with bytes themselves
FILE * fptr = fopen (filename, mode);

If you are opening a binary file, specify b in mode ... this is ignored on *nix machines but is imp on windows

> 2) read in buffer
If you are reading in text
fgets (buffer, BUFFER_LEN, fptr);  <<read in a line of input
or
fscanf (fptr, "%d %d",buffer, int_var); << read in a string and an int .. observe formatted input using FILE*

If you were working with binary files, yo would typically use fread()

> 3) read & get byte's value in the buffer (a buffer has 4 bytes), and
> represent it in HEX, OCX, DEC, or in string
As shown above .. to print in hex or oc, simply use corresponding printf specifier

> 4) write to file
text file would be written to using fputs or fprintf just like the read calls above
binary file would use fwrite()

Dont forget to close the file

refer to these tutorial
http://www.its.strath.ac.uk/courses/c/section3_11.html#SECTION00011000000000000000
http://www.cs.cf.ac.uk/Dave/C/node18.html#SECTION001860000000000000000

Cheers!
Sunnycoder
0
 
tiger0516Author Commented:
>FILE * is at a higher level that fd ... Internally it would map to an fd but using a FILE * you can read in formatted input and write formatted output .. using fd, you work with bytes themselves

So if I want to speak with Bytes, I'd better to use fd?

0
The Lifecycle Approach to Managing Security Policy

Managing application connectivity and security policies can be achieved more effectively when following a framework that automates repeatable processes and ensures that the right activities are performed in the right order.

 
tiger0516Author Commented:
Many thanks. Very helpful!

Let me read the two URLs you gave first.
0
 
tiger0516Author Commented:
The following code reads data from a binary file. First, it read 4 bytes, if the value represented by these 4 bytes is 2, then the code read next 2 byte's data; if it is 4, then read next 4 byte's data. Then the code repeat to do this until EOF.

Could you pls illustrate how to use FILE/fopen/fread to do the same stuff ? I tried. I understand this code, criteria is the value represented by next n bytes. I am sure it can be done with FILE/fopen/fread.

(By the way, I think all data in computer is 0-1. So, when I read/write files, is it up to me to decide what kind of format I will see? i.e. printf %c / %d will display differently in the monitor.)

int buff,bytes=4;
file_open = open(argv[1], O_RDONLY);

criteria = read( file_open, &buff, bytes);

  while( criteria != 0 )
  {

    criteria = read(file_open, &buff, bytes); //How many bytes shall I read next (used in if-else clause)
    if( buff == 2 )
    {
      criteria = read(file_open, &buff, 2);  //Ok, the following is a short int, read next 2 bytes
    }

    if( buff == 4 )
    {
      criteria = read(file_open, &buff, 4); //Ok, the following is a long int, read next 4 bytes
    }
 
   }
0
 
sunnycoderCommented:
>By the way, I think all data in computer is 0-1. So, when I read/write files, is it up to me to decide what kind of format I will
>see? i.e. printf %c / %d will display differently in the monitor.
Yes and No ... 1 might be stored as integer value 1 or it could be character 1 (integer value = ASCII/code value of 1) ... As you might have noticed, the bit sequence is different, your format specifier would be different yet the value you will see on screen would be the same. So it depends on bit sequence + how you interpret the bit sequence (format specifier)

>Could you pls illustrate how to use FILE/fopen/fread to do the same stuff ? I tried.
Good .. let us try to get your code working .. show the code

>criteria is the value represented by next n bytes
From the read man page
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. Perhaps this was the reason your code was not working as expected
0
 
tiger0516Author Commented:
>Good .. let us try to get your code working .. show the code

I simply lost.

First, a while loop control while (fread(buffer,1,4,fp)>0), but I think the logic comparison> here is not accurate, since it is possible to return a value>0 but still error exists (?).

Then a for loop for (i=0; i<4; i++)

buffer[0]~buffer[3] store 1st ~ 4th bytes' value respectively. (I also think the while control above may cause, sometimes, buffer[i] out of index error.

Then?
0
 
sunnycoderCommented:
>but I think the logic comparison> here is not accurate, since it is possible to return a value>0 but still error exists (?).
From the man page again
fread and fwrite return the number of items successfully read or written (i.e., not the number of characters). If an error occurs, or the end-of-file is reached, the return value is a short item count (or zero).

read does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred

That should be clear enough!! If you need further clarifications on this, post back .. also make it a habit to refer to man pages .. it takes a while to get accoustomed to them but it is extremely helpful in the long run

> (I also think the while control above may cause,
>sometimes, buffer[i] out of index error.
The loop will exit as soon as i reaches value 4 ... uptil 3 are valid indices ... since value at index 4 will never be accessed (only value of i will be tested) so there would never be an out of index error ... on a side note, C does not detect invalid index accessing ... such access generally leads to logical errors or segementation faults.

Overall you are on the right track ... just put it all down together and you would have the complete program in no time.

Cheers!
sunnycoder
0
 
tiger0516Author Commented:
I want an explicit answer. I opened a new topic at http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_21855509.html 

Could u pls take a look?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.