C Programming

Read() Function in C Language

The C language has two basic functions that allow you to read the files using the read() and fread() functions. It also has methods with functions to read the files character-by-character.

It is important to know the file processing functions, their call methods, input and output arguments, etc., in order to use them fluently because they are the resource available to the programmer to store and dispose of the information that is stored in the system.

In this Linux Hint article, you will learn how to use the read() function to read the files.

We’ll explain everything about “ella”, its syntax, the method call, the input and output arguments, the type of data that they each accept, and how to declare them properly.

We then apply what we learned by putting the use of this feature into practical examples.

In order for you to be fully aware of how to use the read() function, we added a special section which describes all the errors that can occur when using this function, as well as their detection and identification, so that you have the necessary techniques for a quick solution in case of an error.

Syntax of the Read() Function in C Language

size_t read(int fd, void *buf, size_t count);

Description of the Read() Function in C Language

The read() function reads the contents of the open file which is specified by its descriptor in the “fd” input argument. This function reads and copies the count number of bytes into the buffer that is pointed to by buf. The “fd” identifier is an integer that is returned as the result of the open() function when the file is opened.

If the read() function returns successfully, it returns the number of bytes read. A result that is equal to 0 means that the file is read to the end, and -1 means that an error occurs. The specific error can be identified by retrieving its code from the errno global variable. Later, you will find a section which describes the errors that can occur when using the read() function and the techniques to detect and identify them.

The read() function is declared in the “unistd.h” header. To use it, you must include this file in your code as follows:

#include <unistd.h>

How to Read a File with the Read() Function in C Language

In this example, we will explain how to open and read a file using the open() and read() functions.

For this purpose, we previously created a text file with the name, “example.txt”, via the Linux Manager and saved it in the “Documents” directory. We wrote the first paragraph of this article in it.

The first step in developing the code to read the file is to include the necessary headers and create a main() function that returns an empty value. We define the “fd” integer in it which serves as the file descriptor, a 1024 character buffer called “buff” where the information that is read by the read() function is stored. The array path stores the path and the name of the file that we want to read.

After defining the necessary variables, we call the open() function to open the file. We call this function by passing the path array with the path and name of the file as the first input argument and specifying the O_RDONLY flag as the second argument. We pass the “fd” integer as the output argument where open() returns the descriptor that we use to read to the file.

Once we have the file open, we read its contents by calling the read() function and passing the “fd” descriptor that is returned by the open() function as the first argument. We pass the pointer to the “buff” buffer as the second argument where we store the contents to be read. Finally, we pass the size of the buffer which is 1024 bytes in this case. We then use the printf() function to display the contents that are stored in “buff” in the command console.

Here is the complete code for this example:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main()
{  
   intfd;
   char buff[1024];
   char path[] = "Documents/example.txt";

   fd = open(path, O_RDONLY);
   read(fd, buff, 1024);

   printf("\n\n%s\n\n",buff);
}

In the following figure, we see the compilation and execution of this code. As we can see, read() puts the entire contents of the “example.txt” file into “buff” and the printf() function prints it to the command console:

How to Detect and Identify the Errors That Can Occur When Using the Read() Function in the C Language

Using read() can generate various errors. When this happens, this function returns a result that is equal to -1.

The easiest way to determine if an error has occurred is to use an “if” condition where the condition is the return value of -1. Now, let us see how you can use this method to determine if an error has occurred:

int n;
n = read(fd, buff , 1024);

if ( n == -1){

    printf ("An error occurred while trying to read the file.");
}

If the read() function returns with an error, it transitions to the “if” statement and prints the message, “An error occurred while trying to read the file”.

When an error occurs, a numeric code is automatically stored in the errno global variable which is defined in the “errno.h” header. This code can be used to identify the error that occurred.

The following is an excerpt with the errors that the read() function can generate and that are defined in the “errno.h” header, along with a brief description of each error and the associated integer value:

Definition Value in errno Error
EAGAIN 11 Try again.
EBADF 9 Incorrect file number.
EDESTADDRREQ 89 Destination address required.
EFAULT 14 Incorrect address.
EFBIG 27 File too big.
EINTR 4 System call interrupted.
EINVAL 22 Invalid argument.
EIO 5 I/O error.
EPERM 1 Operation not allowed.

The easiest way to identify an error is to open a switch where the errno variable is the jump condition and each case is an error definition.

Next, let us look at an example where we try to enter a descriptor with a negative sign, resulting in an error. To identify an error, we use the “if” condition that we saw in the previous snippet. To identify it, we open a switch with the three most common errors that this function can produce.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main() {
 
  intfd,n;
  char buff[1024];
  char path[] = "Documents/example.txt";

   fd = open(path, O_RDONLY);
   n = read(0, buff, 1024);
   
   if (n == -1){
   
    switch(errno){
    case EBADF:{
            printf("Bad file number. Error: %i\n", errno);
            break;}
    case EINVAL:{
            printf("Invalid argument. Error: %i\n", errno);
            break;}
    case EIO:{
            printf("I/O error . Error: %i\n", errno);
            break;}
    }
 }
}

As we can see in the following figure, the read() function returns an error when an invalid descriptor is passed as an input argument. The value that is retrieved from the errno variable is used as a jump condition which allows us to identify the error when we enter the EBADF case.

Conclusion

In this Linux Hint article, we showed you how to use the read() function, one of the most common functions that is implemented in the C language to read the files.

We looked at its syntax and a section which describe its theoretical operation, input and output arguments, and its data types. Afterwards, we implemented what we learned through a practical example with code and images that shows how to open and read a file using the open() and read() functions.

To have the necessary means to troubleshoot a possible error when using this function, we added a special section which explains the methods that the C language provides to detect and identify the errors.

About the author

Julio Cesar

Julio Cesar is a 42 years old programmer with 8 years of experience in embedded systems development, 6 years developing firmware for user interfaces in C and C++. Additionally he has 2 years of experience developing scripts for network devices and 3 years as developer of high frequency PCB (Printed Circuit Board).