File input and output (I/O) operations are essential in C programming for reading data from files and writing data to files. This capability allows programs to interact with external files, enabling data persistence and communication between programs. In this chapter, we will explore the concepts of file I/O, from basic operations to advanced techniques, using clear examples and detailed explanations.
To begin operations on a file, it must be opened using the fopen()
function. This function requires the filename and the mode of operation as parameters. Modes include read ("r"
), write ("w"
), and append ("a"
).
FILE *file_pointer;
file_pointer = fopen("filename.txt", "r");
After completing file operations, it’s essential to close the file using fclose()
to release system resources associated with it.
fclose(file_pointer);
Reading data from a file is achieved using functions like fscanf()
or fgets()
to read individual elements or entire lines, respectively.
fscanf(file_pointer, "%d", &number);
fgets(buffer, sizeof(buffer), file_pointer);
Writing data to a file involves using functions like fprintf()
or fputs()
to write formatted output or strings to the file.
fprintf(file_pointer, "The value is: %d\n", value);
fputs("Hello, world!\n", file_pointer);
It’s essential to handle errors that may occur during file operations. Checking if the file pointer is NULL
after opening a file is a common practice.
if (file_pointer == NULL) {
printf("File open error!");
return 1;
}
In addition to text files, C supports reading and writing binary files. For binary file I/O, functions like fwrite()
and fread()
are used to handle binary data.
fwrite(data, sizeof(data[0]), num_elements, file_pointer);
fread(data, sizeof(data[0]), num_elements, file_pointer);
The fseek()
function allows positioning the file pointer at a specific location within the file, enabling random access to data.
fseek(file_pointer, offset, SEEK_SET); // SEEK_SET, SEEK_CUR, SEEK_END
Explanation:
offset
: Number of bytes to move the file pointer.SEEK_SET
, SEEK_CUR
, SEEK_END
: Constants indicating the starting point for seeking.
SEEK_SET
sets the file pointer relative to the beginning of the file.SEEK_CUR
sets the file pointer relative to its current position.SEEK_END
sets the file pointer relative to the end of the file.This example demonstrates reading data from a text file named “input.txt”.
#include
int main() {
FILE *file_pointer;
char buffer[100];
file_pointer = fopen("input.txt", "r");
if (file_pointer == NULL) {
printf("File open error!");
return 1;
}
fgets(buffer, sizeof(buffer), file_pointer);
printf("Data read from file: %s", buffer);
fclose(file_pointer);
return 0;
}
"r"
).NULL
to handle any errors during file opening.fgets()
, it reads a line from the file and stores it in the buffer
array.fclose()
to release system resources.Output: If “input.txt” contains the text “Hello, world!”:
This example demonstrates writing data to a text file named “output.txt”.
#include
int main() {
FILE *file_pointer;
int value = 100;
file_pointer = fopen("output.txt", "w");
if (file_pointer == NULL) {
printf("File open error!");
return 1;
}
fprintf(file_pointer, "The value is: %d\n", value);
fclose(file_pointer);
return 0;
}
"w"
).NULL
to handle any errors during file opening.fprintf()
, it writes formatted data to the file.fclose()
.Output: A file named “output.txt” is created with the content “The value is: 100”.
This example demonstrates appending data to a text file named “data.txt”.
#include
int main() {
FILE *file_pointer;
file_pointer = fopen("data.txt", "a");
if (file_pointer == NULL) {
printf("File open error!");
return 1;
}
fputs("New data appended!\n", file_pointer);
fclose(file_pointer);
return 0;
}
"a"
).NULL
to handle any errors during file opening.fputs()
, it appends a string to the end of the file.fclose()
.Output: If “data.txt” already contains some data, the new string “New data appended!” will be added to the end of the file.
This example demonstrates reading and writing binary data to a binary file named “binary_data.bin”.
#include
int main() {
FILE *file_pointer;
int data_write[] = {10, 20, 30, 40, 50};
int data_read[5];
// Writing to binary file
file_pointer = fopen("binary_data.bin", "wb");
if (file_pointer == NULL) {
printf("File open error!");
return 1;
}
fwrite(data_write, sizeof(data_write[0]), sizeof(data_write)/sizeof(data_write[0]), file_pointer);
fclose(file_pointer);
// Reading from binary file
file_pointer = fopen("binary_data.bin", "rb");
if (file_pointer == NULL) {
printf("File open error!");
return 1;
}
fread(data_read, sizeof(data_read[0]), sizeof(data_read)/sizeof(data_read[0]), file_pointer);
fclose(file_pointer);
// Displaying data read from file
printf("Data read from file: ");
for (int i = 0; i < sizeof(data_read)/sizeof(data_read[0]); i++) {
printf("%d ", data_read[i]);
}
printf("\n");
return 0;
}
data_write
to a binary file named “binary_data.bin” in write mode ("wb"
).data_read
from the same binary file in read mode ("rb"
).
// output //
Data read from file: 10 20 30 40 50
fopen()
):FILE *fopen(const char *filename, const char *mode);
filename
: Name of the file to be opened.mode
: Mode of file access (“r”, “w”, “a”, “rb”, “wb”, “ab”, etc.).NULL
if an error occurs.fclose()
):int fclose(FILE *stream);
stream
: File pointer to the file to be closed.0
if successful, EOF
(end-of-file) if an error occurs.fscanf()
, fgets()
, fread()
, etc.):int fscanf(FILE *stream, const char *format, ...);
char *fgets(char *str, int n, FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
stream
: File pointer to the file from which data is read.format
(for fscanf()
): Format string specifying the data format to read.str
(for fgets()
): Buffer to store the read data.n
(for fgets()
): Maximum number of characters to read.ptr
(for fread()
): Pointer to the buffer where data is to be stored.size
(for fread()
): Size in bytes of each element to be read.nmemb
(for fread()
): Number of elements to be read.EOF
if an error occurs.fprintf()
, fputs()
, fwrite()
, etc.):int fprintf(FILE *stream, const char *format, ...);
int fputs(const char *str, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
stream
: File pointer to the file where data is to be written.format
(for fprintf()
): Format string specifying the format of the data to write.str
(for fputs()
): String to be written.ptr
(for fwrite()
): Pointer to the data to be written.size
(for fwrite()
): Size in bytes of each element to be written.nmemb
(for fwrite()
): Number of elements to be written.feof()
, ferror()
, etc.):int feof(FILE *stream);
int ferror(FILE *stream);
stream
: File pointer to the file being checked.feof()
: Non-zero if end-of-file indicator is set, 0
otherwise.ferror()
: Non-zero if error indicator is set, 0
otherwise.fseek()
):int fseek(FILE *stream, long int offset, int whence);
stream
: File pointer to the file where seeking is performed.offset
: Number of bytes to offset from the reference point specified by whence
.whence
: Reference point for seeking (SEEK_SET
, SEEK_CUR
, SEEK_END
).0
on success, non-zero otherwise.File input and output operations are fundamental in C programming, enabling interaction with external files. Understanding file I/O allows developers to create applications capable of efficient data handling. This chapter equips readers with comprehensive knowledge and practical examples to master file I/O operations effectively, empowering them to tackle diverse file-related tasks with confidence. Happy coding!❤️