-------------------------------------------------------------------------------------
My Training Period: xx hours
//////////// rwbinary.c /////////// ///// FEDORA 3, gcc x.x.x ///// // reading, writing, rewind and binary data #include <stdio.h>
enum {SUCCESS, FAIL, MAX_NUM = 5};
// function prototypes... void DataWrite(FILE *fout); void DataRead(FILE *fin); int ErrorMsg(char *str);
int main(void) { FILE *fptr; // binary type files... char filename[] = "/testo1/testo2/teseight.bin"; int reval = SUCCESS;
// test for creating, opening binary file for writing... if((fptr = fopen(filename, "wb+")) == NULL) { reval = ErrorMsg(filename); } else { // write data into file teseight.bin DataWrite(fptr); // reset the file position indicator... rewind(fptr); // read data... DataRead(fptr); // close the file stream... if(fclose(fptr) == 0) printf("%s successfully closed\n", filename); } return reval; }
// DataWrite() function definition void DataWrite(FILE *fout) { int i; double buff[MAX_NUM] = {145.23, 589.69, 122.12, 253.21, 987.234};
printf("The size of buff: %d-byte\n", sizeof(buff)); for(i=0; i<MAX_NUM; i++) { printf("%5.2f\n", buff[i]); fwrite(&buff[i], sizeof(double), 1, fout); } }
// DataRead() function definition void DataRead(FILE *fin) { int i; double x;
printf("\nReread from the binary file:\n"); for(i=0; i<MAX_NUM; i++) { fread(&x, sizeof(double), (size_t)1, fin); printf("%5.2f\n", x); } }
// ErrorMsg() function definition int ErrorMsg(char *str) { printf("Cannot open %s.\n", str); return FAIL; }
[root@bakawali bodo]# gcc rwbinary.c -o rwbinary [root@bakawali bodo]# ./rwbinary
The size of buff: 40-byte 145.23 589.69 122.12 253.21 987.23
Reread from the binary file: 145.23 589.69 122.12 253.21 987.23 /testo1/testo2/teseight.bin successfully closed
|
The following sections compiled from GNU glibc library documentation, provide a summary and other collections that you may interested related to file I/O. Sockets will be discussed in another Module. It looks that the file attributes also not discussed here.
The following Table describes functions for performing character and line-oriented output.
These narrow streams functions are declared in the header file stdio.h and the wide stream functions in wchar.h.
int fputc(int c, FILE *stream) |
The |
wint_t fputwc(wchar_t wc, FILE *stream) |
The |
int fputc_unlocked(int c, FILE *stream) |
The |
int putc(int c, FILE *stream) |
This is just like |
wint_t putwc(wchar_t wc, FILE *stream) |
This is just like |
int putc_unlocked(int c, FILE *stream) |
The |
int putchar(intc) |
The |
wint_t putwchar(wchar_twc) |
The |
int putchar_unlocked(intc) |
The |
int fputs(const char *s, FILE *stream) |
The function
Outputs the text |
int fputws(const wchar_t *ws, FILE *stream) |
The function |
int puts(const char *s) |
The
Outputs the text |
Table 9.11: Output by characters or lines functions |
This section describes functions for performing character-oriented input. These narrow streams functions are declared in the header file stdio.h and the wide character functions are declared in wchar.h.
These functions return an int or wint_t value (for narrow and wide stream functions respectively) that is either a character of input, or the special value EOF/WEOF (usually -1). For the narrow stream functions it is important to store the result of these functions in a variable of type int instead of char, even when you plan to use it only as a character.
Storing EOF in a char variable truncates its value to the size of a character, so that it is no longer distinguishable from the valid character (char) -1.
So always use an int for the result of getc() and friends, and check for EOF after the call; once you've verified that the result is not EOF, you can be sure that it will fit in a char variable without loss of information.
int fgetc(FILE *stream) |
This function reads the next character as an |
wint_t fgetwc(FILE *stream) |
This function reads the next wide character from the stream stream and returns its value. If an end-of-file condition or read error occurs, |
int fgetc_unlocked(FILE *stream) |
The |
int getc(FILE *stream) |
This is just like |
wint_t getwc(FILE *stream) |
This is just like |
int getc_unlocked(FILE *stream) |
The |
int getchar(void) |
The |
wint_t getwchar(void) |
The |
int getchar_unlocked(void) |
The |
Table 9.12: Character oriented input functions |
An example of a function that does input using fgetc(), it would normally work just as well using getc() instead, or using getchar() instead offgetc(stdin). The code would also work for the wide character stream functions as well.
Since many programs interpret input on the basis of lines, it is convenient to have functions to read a line of text from a stream. Standard C functions for these tasks aren't very safe: null characters and even (for gets()) long lines can confuse them.
This vulnerability creates exploits through buffer overflows. That is why you see warning everywhere; you may check your implementation documentation for safer version of those functions. All these functions are declared in stdio.h.
char * fgets(char *s, int count, FILE *stream) |
The If the system is already at end of file when you call Warning: If the input data has a null character, you can't tell. So don't use |
wchar_t * fgetws(wchar_t *ws, int count, FILE *stream) |
The If the system is already at end of file when you call Warning: If the input data has a null wide character (which are null bytes in the input stream), you can't tell. So don't use |
char * gets(char *s) |
The function Warning: The |
Table 9.13: Line oriented input functions |
D. Block Input/Output
|
size_t fread(void *data, size_t size, size_t count, FILE *stream) |
This function reads up to count objects of size size into the array data, from the stream stream. It returns the number of objects actually read which might be less thancount if a read error occurs or the end of the file is reached. This function returns a value of zero (and doesn't read anything) if either size or count is zero. If |
size_t fwrite(const void *data, size_t size, size_t count, FILE *stream) |
This function writes up to count objects of size size from the array data, to the stream stream. The return value is normallycount, if the call succeeds. Any other value indicates some sort of error, such as running out of space. |
Table 9.14: Block oriented I/O functions |
You can delete a file with unlink() orremove().
Deletion actually deletes a file name. If this is the file's only name, then the file is deleted as well. If the file has other remaining names, it remains accessible under those names.
int rmdir(const char *filename) |
The |
int remove(const char *filename) |
This is the ISO C function to remove a file. It works like |
Table 9.15: Remove directory and file functions |
Therename() function is used to change a file's name.
int rename(const char *oldname, const char *newname) |
The The directory containing the namenewname must be on the same file system as the directory containing the name oldname. One special case for If oldname is not a directory, then any existing file named newname is removed during the renaming operation. However, if newname is the name of a directory, If oldname is a directory, then either newname must not exist or it must name a directory that is empty. In the latter case, the existing directory named newname is deleted first. The name newname must not specify a subdirectory of the directory One useful feature of |
Table 9.16: Rename function |
Directories are created with the mkdir() function. There is also a shell command mkdir() which does the same thing.
int mkdir(const char *filename, mode_t mode) |
The |
Table 9.17: Create directory function |
A pipe is a mechanism for interprocess communication; data written to the pipe by one process can be read by another process. The data is handled in a first-in, first-out (FIFO) order. The pipe has no name; it is created for one use and both ends must be inherited from the single process which created the pipe.
A FIFO special file is similar to a pipe, but instead of being an anonymous, temporary connection, a FIFO has a name or names like any other file. Processes open the FIFO by name in order to communicate through it.
A pipe or FIFO has to be open at both ends simultaneously. If you read from a pipe or FIFO file that doesn't have any processes writing to it (perhaps because they have all closed the file, or exited), the read returns end-of-file. Writing to a pipe or FIFO that doesn't have a reading process is treated as an error condition; it generates a SIGPIPE signal, and fails with error code EPIPE if the signal is handled or blocked.
Neither pipes nor FIFO special files allow file positioning. Both reading and writing operations happen sequentially; reading from the beginning of the file and writing at the end.