The C language has several functions that allow to read the files, the most commonly used are the read() and fread() functions. This language also provides methods to read the character by character with functions such as getchar().
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 available resource to the programmer to store and dispose off the information that is stored in the system.
In this Linuxhint article, you will learn how to use the read() function to read the files.
We’ll explain everything about this ella, its syntax, the method call, the input and output arguments, the type of data 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 on how to use the read() function, we added a special section that describes all the errors that can occur when using this function, as well as their detection and identification, so that you will 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
The read() function reads the contents of the open file that is specified by its descriptor in the “fd” input argument. This function reads and copies the contents of the file into the buffer that is pointed to by “buf” with the count number of bytes. 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 equal to 0 means that the file was read to the end, and -1 means that an error occurred.
The specific error can be identified by retrieving its code from the global “errno” variable. Later, you will find a section that 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 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 “example.txt” name via the Linux Manager and saved it in the “Documents” directory. Then, 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 read() 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. As the output argument, we pass the “fd” integer where open() returns the descriptor that we then 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 as the first argument that is returned by the open() function. As the second argument, we pass the pointer to the “buff” buffer where we store the contents to be read and finally the size of the buffer which, in this case, is 1024 bytes.
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 <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd;
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
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:
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 “An error occurred while trying to read the file” message.
When an error occurs, a numeric code is automatically stored in the global “errno” 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 <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int main()
{
int fd,n;
char buff[1024];
char path[] = "Documents/example.txt";
fd = open(path, O_RDONLY);
n = read(99999999, 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, and the value that is retrieved from the “errno” variable that is used as a jump condition allows us to identify the error when entering the EBADF case.
Conclusion
In this Linuxhint 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 that describes its theoretical operation, input and output arguments, and its data types. Afterwards, we implemented what we learned in a practical example with the code and images that show 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 that explains the methods that the C language provides to detect and identify the errors.