How to Read Until End of File in C

Waqar Aslam Feb 02, 2024
  1. Overview of End-of-File (EOF) in C
  2. File Handling in C
  3. Read Until the End of the File Using the fgetc Function
  4. Read Until the End of the File Using the fgets Function
  5. Read Until the End of the File Using the fread() Function
  6. Conclusion
How to Read Until End of File in C

In this article, we’ll explain how to read until end-of-file using the C programming language. Programmers often encounter this when processing files, ensuring they capture every piece of information.

This guide unveils diverse approaches, presenting step-by-step procedures in simple terms. Whether handling text or binary data, these techniques empower programmers to navigate files seamlessly.

Overview of End-of-File (EOF) in C

EOF serves as a sentinel value that marks the conclusion of a file, signaling that there is no more data to be read. It’s crucial to recognize and appropriately handle EOF to ensure accurate and efficient file processing.

File Handling in C

File handling is a crucial aspect of C programming, enabling developers to interact with external data stored in files. The ability to read from and write to files is fundamental for tasks such as data storage, retrieval, and manipulation.

In C, several key functions facilitate efficient file handling, each serving a specific purpose in managing file operations.

fopen() This function is used to open a file.
fclose() This is used to close files after performing file operations on them.
fread() This reads data from a file into a specified memory location.
fwrite() This writes data from a file into a specified memory location.
fscanf() This reads formatted data from a file.
fprintf() This is used to write formatted data to a file.

Read Until the End of the File Using the fgetc Function

In C, the fgetc() function is a versatile tool for reading the contents of a file until the end is reached.

The fgetc() function in C is part of the standard input/output library (stdio.h). It is used to read a single character from a file.

Syntax:

int fgetc(FILE *stream);

Here, stream is a pointer to a FILE object, which represents the file to be read.

The fgetc() function reads the next character from the specified file and returns its ASCII value as an integer. If the end of the file (EOF) is reached, it returns the constant EOF (which is usually defined as -1).

Here’s a simple example of using fgetc() to read characters from a file until the end of the file:

example.txt:

Hello, World!

Example:

#include <stdio.h>

int main() {
  FILE *file = fopen("example.txt", "r");

  if (file == NULL) {
    perror("Error opening file");
    return 1;
  }

  int character;

  // Reading until the end of the file
  while ((character = fgetc(file)) != EOF) {
    putchar(character);
  }

  fclose(file);

  return 0;
}

In this code example, we begin by opening a file named example.txt in read mode (r). The fopen() function returns a pointer to the file, and we perform a check to ensure that the file was successfully opened.

An if-else statement is used to check in case there’s an issue opening the file. The perror() function prints a descriptive error message, and the program exits with an error code.

Next, we see the core of the program, which is a while loop that uses the fgetc() function. The fgetc() reads one character at a time from a file pointed to by file.

The while loop continues until the end of the file is encountered, denoted by the condition (character = fgetc(file)) != EOF. Lastly, the file is closed using the fclose() function.

Output:

Hello, World!

After running the program, the output shows that it read and printed every character inside the example.txt file.

The fgetc() method provides a straightforward and efficient way to read a file character by character until the end is reached. This technique is essential for various applications, from simple text processing to more complex data analysis tasks.

Read Until the End of the File Using the fgets Function

In C, the fgets() function is a versatile tool for reading lines from a file. By mastering file input with fgets(), programmers gain a robust tool for handling diverse file formats and extracting information systematically.

Syntax:

char *fgets(char *str, int n, FILE *stream);

Here, str is a pointer to the character array where the read line will be stored, n is the maximum number of characters to be read (including the null-terminating character), and stream is the file stream from which to read the line.

The fgets() function reads characters from the specified file stream until one of the following conditions is met: a newline character (\n) is encountered, n - 1 characters have been read (maximum number of characters specified by the second argument), or the end of file is reached.

example.txt:

Hello, World!
This is a sample file.
Read until the end with fgets().

Example:

#include <stdio.h>

int main() {
  FILE *file = fopen("example.txt", "r");

  if (file == NULL) {
    perror("Error opening file");
    return 1;
  }

  char buffer[1024];

  // Reading lines until the end of the file
  while (fgets(buffer, sizeof(buffer), file) != NULL) {
    printf("%s", buffer);
  }

  fclose(file);

  return 0;
}

In this code example, the heart of the program lies in the while loop that uses the fgets() function. The fgets() reads a line from the file into the buffer array with a specified size of 1024.

In this case, 1024 is often chosen as the size of the buffer array since it’s a reasonable size that accommodates typical line lengths and is efficient in terms of memory usage. Adjusting this value depends on the expected line lengths in your application.

Inside the while loop, each line read from the file is printed to the standard output using printf(). This allows us to visualize the contents of the file, line by line.

The while loop continues until fgets() returns NULL, indicating the end of the file.

Output:

Hello, World!
This is a sample file.
Read until the end with fgets().

If the code runs successfully, all the characters inside the example.txt file will be printed to the console.

Utilizing fgets() in a loop is an effective way to read a file line by line until the end is reached. This approach is particularly valuable when dealing with structured data or text files containing records separated by newline characters.

Read Until the End of the File Using the fread() Function

In scenarios where large volumes of binary data need processing, the fread() function in C becomes a powerful ally. By mastering file input with fread(), programmers gain a robust tool for handling binary data efficiently.

Syntax:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

Parameter:

  • ptr: A pointer to the block of memory where the data read from the file will be stored.
  • size: The size (in bytes) of each element to be read.
  • nmemb: The number of elements, each of size size, to be read.
  • stream: A pointer to a FILE object, which represents the file stream from which the data is to be read.

To understand better how this works, below is an example code that utilizes the fread() function, which reads until end-of-file.

binaryfile.bin:

4A 50 47 33 2E 35 0A 48 46 69 6C 65

Example:

#include <stdio.h>

int main() {
  FILE *file = fopen("binaryfile.bin", "rb");

  if (file == NULL) {
    perror("Error opening file");
    return 1;
  }

  char buffer[1024];

  // Reading until the end of the file using fread
  size_t bytesRead;
  while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0) {
    // Process the data in the buffer (example: print to stdout)
    fwrite(buffer, 1, bytesRead, stdout);
  }

  fclose(file);

  return 0;
}

In this example, we first attempt to open a binary file named binaryfile.bin in read-binary mode (rb). The fopen() function returns a pointer to the file, and a check ensures that the file was opened successfully.

The main part of this program is the while loop that uses the fread() function. fread() reads a specified number of elements (1 byte in this case) into the buffer array.

The 1024 in char buffer[1024] represents the size of the character array (buffer) used to store each line of text. It is a common practice to use powers of 2 for buffer sizes for efficiency.

Inside the while loop, the data in the buffer can be processed. In this example, the data is simply printed to the standard output using fwrite().

The loop continues until fread() returns zero, indicating the end of the file.

Output:

4A 50 47 33 2E 35 0A 48 46 69 6C 65

Since the binaryfile.bin file was successfully read using the fread() function, running the program would print the characters of the file onto the console.

Employing fread() in a loop is a potent method for reading binary data from a file until its end. This technique is particularly beneficial when dealing with large files or binary formats.

Conclusion

Throughout this article, we’ve tackled various methods for reading until the end of a file, each with its strengths and use cases.

The fgetc() method provides a character-by-character approach, reading until the end of a file. It is straightforward and effective for processing text files, allowing for real-time character handling.

Utilizing fgets() in a loop allows for reading file content line by line. This method is particularly useful for processing text files where lines are meaningful units of data.

Employing fread() in a loop is a powerful technique for reading binary data efficiently. It excels in scenarios where data is stored in a binary format, offering control over the number of bytes read at a time.

Each method has its strengths, and the choice depends on the specific requirements of the task at hand. Whether dealing with text or binary files, understanding these methods equips programmers with the tools needed to handle file input effectively, ensuring reliable and efficient data processing in C programs.

Author: Waqar Aslam
Waqar Aslam avatar Waqar Aslam avatar

I am Waqar having 5+ years of software engineering experience. I have been in the industry as a javascript web and mobile developer for 3 years working with multiple frameworks such as nodejs, react js, react native, Ionic, and angular js. After which I Switched to flutter mobile development. I have 2 years of experience building android and ios apps with flutter. For the backend, I have experience with rest APIs, Aws, and firebase. I have also written articles related to problem-solving and best practices in C, C++, Javascript, C#, and power shell.

LinkedIn

Related Article - C File