UNIX advanced environment programming (7) standard I/O function library and I/O function library
1 Binary IO (Binary IO)
In the previous article, we learned about character-by-character read/write and row-by-row read/write functions.
If we want to read and write binary files and want to read and write the entire file, although these two functions can be implemented, they will obviously be troublesome and the efficiency will be very low for multiple cycles.
To cope with this scenario, the standard IO Library provides fread and fwrite functions.
Function declaration:
#include <stdio.h>
size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);
size_t fwrite(const void *restrict ptr, size_t size size_t nobj, FILE *restrict fp);
Function usage;
A) read and write an array.
float data[10];
if (write(&data[2], sizeof(float), 4, fp) != 4)
err_sys(“fwrite error");
In this example, four float data types are read from the stream fp and filled in to the positions from 2 to 5 in the array table.
B) read and write a struct.
struct {
short count;
long total;
char name[NAMESIZE];
} item;
if (fwrite(&item, sizeof(item), 1, fp) != 1)
err_sys(“fwrite error");
In this example, read data from fp and fill in a struct.
The above two examples can be considered as reading and writing an array of a struct. The parameter size is the length of the struct, and the parameter nobj is the number of elements to be read and written in the array.
Function return value:
The return values of both functions are the number of read/write elements.
The return value of a READ function may be smaller than that of nobj. if an exception is thrown or the end of the file is read. In this case, you need to call the function ferror or feof to determine.
If the return value of a write function is smaller than that of nobj, an exception is thrown.
Function details:
In the above example, we use the fwrite function to fill in a struct. If the read and write operations are not in the same system, the memory layout of the struct may be different, this is common in current multi-system interconnection scenarios. We will continue to look at this issue when discussing the socket. The actual solution is to use the same protocol when reading and writing binary data between different systems.
2 Positioning a Stream)
We have three methods to locate convection:
- Functions: ftell and fseek. Store the current offset of the file in the long integer variable;
- Functions: ftello and fseeko. Store the current offset of the file in the off_t variable;
- Functions: fgetpos and fsetpos. Use the Data Type fpos_t to record the current offset of the file.
Ftell and fseek function declaration:
#include <stdio.h>
long ftell(FILE* fp); // Returns:current file position indicator if OK, -1L on error
int fseek(FILE* fp, long offset, int whence); // Returns:0 if OK , -1 on error
void rewind(FILE* fp);
Function details:
- The offset of a binary file is the number of bytes starting from the file to the current position;
- The ftell function returns the offset of the current file;
- The fseek function is used to locate a file to a specified offset;
- The fseek function's parameter whence is used to set the calculation offset. SEEK_SET indicates calculation starting from the beginning of the file, SEEK_CUR indicates calculation starting from the current offset position of the file, and SEEK_END indicates calculation starting from the end of the file.
- For some non-Unix operating systems, the storage formats of text files are different. The current file offset cannot be expressed by the number of bytes. In this case, the whence parameter must be set to SEEK_SET, in addition, offset only has two values: 0, which indicates the beginning of the inverted text; the other value is the return value of the function ftell.
Ftello and fseeko function declaration:
#include <stdio.h>
off_t ftello(FILE* fp); // Returns: current file position indicator if OK, (off_t) -1 on error
int fseeko(FILE* fp, off_t offset, int whence); /// Returns: 0 if OK, -1 on error
Function details:
- The two functions are the same as the ftell and fseek functions above, except that the return value type is not long, but off_t. in implementation, the expression range of off_t can be larger.
Fgetpos and fsetpos function declaration:
#include <stdio.h>
int fgetpos(FILE* restrict fp, fpos_t *restrict pos);
int fsetpos(FILE* fp, const fpos_t pos);
Function details:
- The fgetpos function saves the current file offset to the parameter pos.
- The pos obtained by fgetpos can be used to set the current file offset to the previous position using fsetpos.
3. format input/output formatted output function
Five printf functions are used to format the output.
Function declaration:
#include <stdio.h>
int printf(const char *restrict format, ...);
int fprintf(FILE *restrict fp, const char *restrict format, ...);
int dprintf(int fd, const char *restrict format, ..);
// All three return : number of characters output if OK , negative value if output error
int sprintf(char *resrict buf, const char *restrict format, ...);
// Returns: number of characters stored in array if OK, negative value if encoding error
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
// Returns: number of characters,that would have been stored in array if buffer was large enough, negative value if encoding error
Function details:
- Printf output to standard output;
- Fprintf is output to the specified stream;
- Dprintf is output to the specified file descriptor;
- Sprintf writes the formatted string to the specified buffer array. It automatically adds a null terminator at the end, but does not include it in the return value. In addition, sprintf may cross the border when the buffer is not large enough, therefore, the user must ensure that the buffer is large enough;
- Snprintf prevents out-of-boundary. The buffer size parameter is added to the springf parameter. All characters written out of the boundary are ignored. If the returned value is smaller than the buffer length, the output is not truncated.
Format Input Functions
Function declaration:
#include <stdio.h>
int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(const char *restrict buf, const char *restrict format, ...);
Function details:
- The format parameter is followed by a parameter that contains the variable address that stores the read string.