← Back to C Course | Chapter 10: File I/O | Lesson 5 of 6

C fseek() & ftell()

fseek and ftell let you jump to any spot in a file and find where you are, like a bookmark in a book. You do not have to read from the start.
Syntax
c
fseek(file_pointer, offset, SEEK_SET);  // or SEEK_CUR, SEEK_END

long position = ftell(file_pointer);

Random access using fseek()

SEEK_SET seeks relative to the file's beginning, SEEK_CUR relative to the current position, and SEEK_END relative to the end -- this flexibility lets you jump anywhere in a file without reading through everything before it.

Example: Random access using fseek()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	FILE *fp = fopen("data.txt", "w");
	fprintf(fp, "0123456789");
	fclose(fp);
	fp = fopen("data.txt", "r");
	fseek(fp, 5, SEEK_SET);
	// Declare c and set it to fgetc(fp)
	char c = fgetc(fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("%c", c);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Finding positions with ftell()

Combining ftell() before and after an operation lets you measure exactly how many bytes a particular read or write consumed, which is useful for building custom file indexes or verifying I/O behavior.

Example: Finding positions with ftell()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	FILE *fp = fopen("data.txt", "w");
	fprintf(fp, "Hello");
	// Declare pos and set it to ftell(fp)
	long pos = ftell(fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("%ld", pos);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Rewinding streams with rewind()

This is functionally identical to fseek(fp, 0, SEEK_SET) but is more concise and self-documenting when all you want is to restart reading a file from its beginning.

Example: Rewinding streams with rewind()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	FILE *fp = fopen("data.txt", "w");
	fprintf(fp, "Hello");
	fclose(fp);
	fp = fopen("data.txt", "r");
	fgetc(fp);
	rewind(fp);
	// Declare c and set it to fgetc(fp)
	char c = fgetc(fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("%c", c);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Calculating file size

The common pattern is fseek(fp, 0, SEEK_END) followed by long size = ftell(fp), then fseek(fp, 0, SEEK_SET) to return to the start before actually reading the data -- this three-step dance is a very common idiom in C file handling.

Example: Calculating file size

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	FILE *fp = fopen("data.txt", "w");
	fprintf(fp, "Hello");
	fclose(fp);
	fp = fopen("data.txt", "r");
	fseek(fp, 0, SEEK_END);
	// Declare size and set it to ftell(fp)
	long size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	fclose(fp);
	// Print formatted text to the screen
	printf("%ld", size);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Moving from EOF using SEEK_END

Negative offsets combined with SEEK_END are the standard way to read a file's last N bytes without reading through the entire file first, which matters for performance on very large files.

Example: Moving from EOF using SEEK_END

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
	FILE *fp = fopen("data.txt", "w");
	fprintf(fp, "0123456789");
	fclose(fp);
	fp = fopen("data.txt", "r");
	fseek(fp, -3, SEEK_END);
	// Declare c and set it to fgetc(fp)
	char c = fgetc(fp);
	fclose(fp);
	// Print formatted text to the screen
	printf("%c", c);
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using ftell on a text file and expecting it to equal the number of characters on some systems.
  2. Forgetting to call rewind or fseek before reading the file again after writing.
  3. Passing the wrong origin constant to fseek, such as mixing up SEEK_SET and SEEK_END.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.