Advanced file handling techniques in C allow greater control and flexibility, enabling efficient data manipulation, random access, and binary file operations. These methods are crucial for handling large datasets, implementing databases, and managing complex file structures.
Function | Description |
---|---|
fseek | Moves the file pointer to a specific position. |
ftell | Returns the current position of the file pointer. |
rewind | Resets the file pointer to the beginning. |
fseek
and ftell
#include <stdio.h>
int main() {
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("Error opening file.\n");
return 1;
}
fseek(fp, 10, SEEK_SET); // Move file pointer 10 bytes from the start
printf("File pointer position: %ld\n", ftell(fp));
char ch = fgetc(fp); // Read the character at the new position
printf("Character at position 10: %c\n", ch);
rewind(fp); // Reset file pointer to the beginning
printf("File pointer reset to: %ld\n", ftell(fp));
fclose(fp);
return 0;
}
Binary files store data in raw format (0s and 1s). Unlike text files, they are not human-readable but are more compact and faster to read/write.
#include <stdio.h>
struct Data {
int id;
char name[20];
float marks;
};
int main() {
struct Data d = {1, "Alice", 95.5};
FILE *fp = fopen("data.bin", "wb");
if (fp == NULL) {
printf("Error opening file.\n");
return 1;
}
fwrite(&d, sizeof(d), 1, fp);
fclose(fp);
return 0;
}
#include <stdio.h>
struct Data {
int id;
char name[20];
float marks;
};
int main() {
struct Data d;
FILE *fp = fopen("data.bin", "rb");
if (fp == NULL) {
printf("Error opening file.\n");
return 1;
}
fread(&d, sizeof(d), 1, fp);
printf("ID: %d, Name: %s, Marks: %.2f\n", d.id, d.name, d.marks);
fclose(fp);
return 0;
}
Use the a
or a+
mode to append data to the end of a file without overwriting existing content.
FILE *fp = fopen("example.txt", "a");
if (fp != NULL) {
fputs("This is appended text.\n", fp);
fclose(fp);
}
Function | Description |
---|---|
ferror | Checks for errors in file operations. |
perror | Prints a descriptive error message. |
clearerr | Resets the error and end-of-file indicators. |
ferror
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
char ch = fgetc(fp);
if (ferror(fp)) {
printf("Error reading file.\n");
}
clearerr(fp); // Reset the error indicator
fclose(fp);
File locking ensures that multiple processes or threads do not interfere with file operations.
#include <stdio.h>
#include <fcntl.h>
int main() {
FILE *fp = fopen("example.txt", "r+");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
int fd = fileno(fp); // Get file descriptor
// Lock file
if (flock(fd, LOCK_EX) == 0) {
printf("File locked successfully.\n");
// Perform operations on the file
flock(fd, LOCK_UN); // Unlock file
} else {
perror("Error locking file");
}
fclose(fp);
return 0;
}
if (remove("file.txt") == 0) {
printf("File deleted successfully.\n");
} else {
printf("Error deleting file.\n");
}
if (rename("oldname.txt", "newname.txt") == 0) {
printf("File renamed successfully.\n");
} else {
printf("Error renaming file.\n");
}
tmpfile
Creates a temporary file that is automatically deleted when closed.
FILE *fp = tmpfile();
if (fp != NULL) {
fputs("Temporary data\n", fp);
fclose(fp); // File is deleted
}
#include <stdio.h>
#include <string.h>
int main() {
FILE *fp = fopen("example.txt", "r+");
if (fp == NULL) {
printf("Error opening file.\n");
return 1;
}
char buffer[100];
char temp[100];
FILE *temp_fp = fopen("temp.txt", "w");
while (fgets(buffer, sizeof(buffer), fp)) {
if (strstr(buffer, "old_word")) {
strcpy(temp, buffer);
char *pos = strstr(temp, "old_word");
strncpy(pos, "new_word", 8); // Replace "old_word" with "new_word"
fputs(temp, temp_fp);
} else {
fputs(buffer, temp_fp);
}
}
fclose(fp);
fclose(temp_fp);
remove("example.txt");
rename("temp.txt", "example.txt");
printf("Search and replace completed.\n");
return 0;
}