Char Fgets (Char STR, Int N, FILE Stream)

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 34

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

#include <stdio.h>

int main()

FILE *fp;

char str[60];

/* opening file for reading */

fp = fopen("file.txt" , "r");

if(fp == NULL)

perror("Error opening file");

return(-1);

if( fgets (str, 60, fp)!=NULL )

/* writing content to stdout */

puts(str);

fclose(fp);

return(0);

2D arrays are generally known as matrix. We will discuss two Dimensional array in
detail but before this have a look at the below piece of code –

#include<stdio.h>
int main()
{
/* 2D array declaration*/
int disp[3][5];

1
/*Counter variables for the loop*/
int i, j;

for(i=0; i<=2; i++)


{
for(j=0;j<=4;j++)
{
printf("Enter value for disp[%d][%d]:", i, j);
scanf("%d", &disp[i][j]);
}
}
return 0;
}

Initialization of 2D Array

There are many ways to initialize two Dimensional arrays –

int disp[2][4] = {
{10, 11, 12, 13},
{14, 15, 16, 17}
};
OR

int disp[2][4] = { 10, 11, 12, 13, 14, 15, 16, 17};
Things which you must consider while initializing 2D array –
You must remember that when we give values during one dimensional array
declaration, we don’t need to mention dimension.  But that’s not the case with 2D
array; you must specify the second dimension even if you are giving values during
the declaration. Let’s understand this with the help of few examples –

/* Valid declaration*/
int abc[2][2] = {1, 2, 3 ,4 } 
/* Valid declaration*/

2
int abc[][2] = {1, 2, 3 ,4 } 
/* Invalid declaration – you must specify second dimension*/
int abc[][] = {1, 2, 3 ,4 }  
/* Invalid because of the same reason  mentioned above*/
int abc[2][] = {1, 2, 3 ,4 }

Store Data into 2D array

...
int abc[5][4];
.....
/*loop for first dimension which is 5 here*/
for(i=0; i<=4; i++)
{
/*loop for second dimension of array which is 4 in this example*/
for(j=0;j<=3;j++)
{
printf("Enter value for abc[%d][%d]:", i, j);
scanf(“%d”, &abc[i][j]);
}
}
In above example, I have a 2D array – abc of integer type. I have used nested for
loops to store data. Conceptually you can consider above array like this –

3
However the actual representation of this array in memory would be something
like –

Pointers & 2D array

4
As we have seen in array that array name alone works as a pointer for the first
element of the array. However in 2D arrays the logic is slightly different. You can
consider a 2D array as collection of several one D arrays.

So abc[0] would represent the address of first element in the first row (if we
consider the above first diagram).
similarly abc[1] would have the address for second row. To understand it better,
lets write a program –
#include <stdio.h>
int main()
{
int abc[5][4] ={
{0,1,2,3},
{4,5,6,7},
{8,9,10,11},
{12,13,14,15},
{16,17,18,19}
};
for (int i=0; i<=3; i++)
{
printf("%d ",abc[i]);
}
return 0;
}
If we consider the memory representation of above diagram then the output would
be –
88202 88218 88234 88250 88266
The above are the addresses of abc[0][0], abc[1][0], abc[2][0], abc[3]
[0] and abc[4][0].

A function is a block of statements, which is used to perform a specific task.


Suppose you are building an application in C language and in one of your program,
you need to perform a same task more than once. So in such scenario you have two
options –

5
a) Use the same set of statements every time you want to perform the task
b) Create a function, which would do the task, and just call it every time you need
to perform the same task.
Using option (b) is a good practice and a good programmer always uses functions
while writing codes.

Types of functions

1) Predefined standard library functions – such


as puts(), gets(),printf(), scanf() etc – These are the functions which already have
a definition in header files (.h files like stdio.h), so we just call them whenever
there is a need to use them.
2) User Defined functions – The functions which we can create by ourselves, for
example in the above code I have created a function abc and I called it in main() in
order to use it.
Why we need functions
Functions are used because of following reasons –
a) To improve the readability of code.
b) Improves the reusability of the code, same function can be used in any program
rather than writing the same code from scratch.
c) Debugging of the code would be easier if you use functions as errors are easy to
be traced.
d) Reduces the size of the code, duplicate set of statements are replaced by
function calls.

Syntax of Defining a function

return_type function_name (argument list)


{
Set of statements – Block of code
}
return_type: Return type can be of any data type such as int, double, char, void,
short etc. Don’t worry you will understand these terms better once you go through
the below examples.

6
function_name: It can be anything, however it is advised to have a meaningful
name for the functions so that it would be easy to understand the purpose of
function just by seeing it’s name.
argument list: Argument list contains variables names along with their data types.
These arguments are kind of inputs for the function. For example – A function
which is used to add two integer variables, will be having two integer argument.
Block of code: Set of C statements, which will be executed whenever a call will be
made to the function.
Above terms are confusing? – Do not worry I’m not gonna end this post until you
learn all of them 
So let’s discuss a problem theoretically – Suppose you want to create a function
which would add two integer variables.
Let me split the problem so that it would be easy to learn –
Function will sum up two numbers so it’s name should be sum, addition, etc… I’m
taking name as addition. The signature would look like –
return_type addition(argument list)
My function is going to add two integer variables, which means I need two integer
variable as input, my function signature would be – I got my argument list –
return_type addition(int num1, int num2)
The result of the sum of two integers would be integer only. Hence function should
return an integer value – I got my return type – It should be integer –
int addition(int num1, int num2);
So you got your function prototype or signature. Now you can add logic to that in
the below example-

How to call a function?

Consider the below program –


Example1:
int addition(int num1, int num2)
{
int sum
/* Arguments are used here*/
sum = num1+num2;

7
/* function return type is integer so I should return some
integer value */
return sum
}

int main()
{
int var1, var2;
printf("enter number 1: ");
scanf("%d",&var1);
printf("enter number 2: ");
scanf("%d",&var2);

/* calling function – function return type is integer so I would be


* needing to store the returned value in some integer variable */
int res = addition(var1, var2);
printf ("Output: %d", res);

return 0;
}
Example2:
/* function return type is void and doesn't have parameters*/
void introduction()
{
printf("Hi\n");
printf("My name is Chaitanya\n");
printf("How are you?");
/* there is no return statement inside this function, since its
* return type is void */
}

int main()
{
/*calling function*/
introduction();

8
return 0;
}
Output:

Hi
My name is Chaitanya
How are you?
Few Points to Note:
1) main () in C program is also a function.
2) Each C program must have at least one function, which is main ().
3) There is no limit on number of functions; A C program can have any number of
functions.
4) A function can call itself and it is known as “Recursion“. I have written a
separate post for it.
Terminologies –which you shouldn’t forget
return type: Data type of returned value. It can be void also, in such case function
doesn’t return any value.
Note: for example, function’s return type is char, then function should return a
value of char type and while calling this function the main() function should have a
variable of char data type to store the returned value.
Structure would look like –

char abc(char ch1, char ch2)


{
char ch3;


return ch3;
}

int main()
{

char c1 = abc('a', 'x');

9
}
Further readings
1) Function – Call by value method – In the call by value method the actual
arguments are copied to the formal arguments, hence any operation performed by
function on arguments doesn’t affect actual parameters.
2) Function – Call by reference method – Unlike call by value, in this method,
address of actual arguments (or parameters) is passed to the formal parameters,
which means any operation performed on formal parameters affects the value of
actual parameters.

This is the default way of calling a function in C. Before I explain it in detail, let’s
discuss about few terms –

Formal arguments: while declaring a function, the arguments list of parameters


we specify are known as formal parameters.
Actual arguments:  The parameter’s value (or arguments) we provide while calling
a function is known as actual arguments.
For example:
int sum(int a, int b)
{
int c=a+b;
return c;
}

int main(
{
int var1 =10;
int var2 = 20;
int var3 = sum(var1, var2);
printf("%d", var3);

return 0;
}

10
In the above example variable a and b are the formal parameters (or formal
arguments). Variable var1 and var2 are the actual arguments (or actual
parameters).

Call by Value

In the call by value method the actual arguments are copied to the formal
arguments, hence any operation performed by function on arguments doesn’t
affect actual parameters. It may sound confusing but let me explain this with the
help of an example –

int increment(int var)


{
var = var+1;
return var;
}

int main()
{
int num1=20;
int num2 = increment(num1);
printf("num1 value is: %d", num1);
printf("num2 value is: %d", num2);

return 0;
}
Output:

num1 value is: 20


num2 value is: 21
Why did it happen? num1 is still have 20 even after increment operation, why?
The reason is simple, function is called by value in above program, which means
num1’s value gets copied into var and the variable var got incremented (not
variable num1), which later stored in num2, via call.
Let’s take another example to understand it –

11
int main( )
{
int num1 = 35, num2 = 45 ;
printf("Before swapping: num1 value is %d and num2 value is %d", num1, num2);

/*calling swap function*/


swapnum ( num1, num2 );
printf("After swapping: num1 value is %d and num2 value is %d", num1, num2);
}

swapnum ( int var1, int var2 )


{
int tempnum ;
/*Copying var1 value into temporary variable */
tempnum = var1 ;

/* Copying var2 value into var1*/


var1 = var2 ;

/*Copying temporary variable value into var2 */


var2 = tempnum ;

}
Output:
After swapping: num1 value is 35 and num2 value is 45
After swapping: num1 value is 35 and num2 value is 45
Why values remain unchanged even after the swap?
The reason is same – function is called by value for num1 & num2. So actually var1
and var2 gets swapped (not num1 & num2). As in call by value actual parameters
are just copied into the formal parameters.

Following are the operations that can be performed on a file –

12
a) Creating a new file
b) Writing into a file
c) Opening an existing file
d) Reading a file
e) Closing a file

Consider a small C program first –

int main()
{
/* Pointer to the file */
FILE *fp1;
/* Character variable to read the content of file */
char c;

/* Opening a file in r mode*/


fp1= fopen ("MYFILE.C", "r");

/* Infinite loop –I have used break to come out of the loop*/


while(1)
{
c = fgetc(fp1);
if(c==EOF)
break;
else
printf("%c", c);
}
fclose(fp1);
return 0;
}
The above program is opening a file MYFILE.C in r mode, reading the content of the
file and displaying it on the console. lets understand the each operation in detail –

Opening a file
13
fopen() function is used to open a file.
Syntax:
FILE pointer_name = fopen ("file_name", "Mode");
here pointer_name can be anything of your choice.
file_name is the name of the file, which you want to open.
While opening a file, you need to specify the mode, detailed information on this
are following –
for example:
FILE *fp;
fp = fopen("MYABC.C", "r");
Above code will open a file MYABC.C in r mode (read only mode). The address of the
first character is stored in pointer fp.
How to track whether file has opened successfully?
As I discussed above, If file is not being open then the pointer will be having NULL
so the below code would help you to track the status –
..
FILE fpr;
fpr = fopen("FILENAME.C", "r");
if (fpr == NULL)
{
puts("Error while opening file");
exit();
}

File Opening Modes:

The file is opened using fopen() function, while opening you can use any of the
below mode as per the need of the program-
Mode “r”: It is a read only mode, which means if the file is opened in r mode, it
won’t allow you to write and modify content of it. When fopen()opens a file
successfully then it returns a pointer to the location, where the file has been
loaded otherwise returns NULL.
Pointer location: On successful opening of file, the fopen() function returns a
pointer, which points to the first character of the file.

14
Mode “w”: It is a write only mode. fopen() creates a new file when the specified
file doesn’t exist and if it fails to open file then it returns NULL.
Mode “a”: Using this mode Content can be appended at the end of an existing file.
Like Mode “w”, fopen() creates a new file if it file doesn’t exist. On unsuccessful
open it returns NULL.
Pointer location: At the last character of the file.
Mode “r+”: This mode is same as mode “r”; however you can perform various
operations on the file opened in this mode. You are allowed to read, write and
modify the content of file opened in “r+” mode.
Pointer location: First character of the file.
Mode “w+”: Same as mode “w” apart from operations, which can be performed;
the file can be read, write and modified in this mode.
Mode “a+”: Same as mode “a”; you can read and append the data in the file,
however content modification is not allowed in this mode.
Reading a File
In order to read, the file must be opened. fopen() returns the address of the file’s
element based on the mode, in which it has been open.
In our example, we have opened a file MYFILE.C in r mode. Pointer fp1 is having
the address of the first element of the file. We have used a functionfgetc() to read
the file.
fgetc ( ): This function reads the character from current pointer’s position and
upon successful reading moves the pointer to next character in the file. Upon
reaching to the end of the file this function returns EOF (End of File). We have
used EOF in our program to determine the end of the file. This is almost similar
to getc() function.
In general, below code is sufficient for reading a file in r mode –
..
char ch;
while(1)
{
/* reading the current character in variable ch and
* moving the pointer forward to point next character*/
ch = fgetc(fp);

/*fgetc wil return EOF when it reaches to the end so

15
* I’m using it to find out the end of the file, since my loop is
* infinite, I need to use break statement to come out of it*/
if (ch ==EOF)
break;
else
/*here I can use any logic, I may write the content in another file
*or I can display it on console*/
printf("%c", ch);
}
..

Writing into a file

Let’s see the code first –

/* I need to write a character into my file so first


* I have stored it into a char variable
*/
char ch = 'a';

/* Syntax is same here, except the mode, I need to write


* the file so I’m using “w” mode
*/
FILE fpw = fopen("MYFILE2.C", "w");

/* fputc is writing ch variable into the address located by fpw


* it also moves the pointer one char forward after each write
*/
fputc(ch, fpw);
Most of the things I have covered in the comments itself. Few things you must note
are: mode “w” for writing, fputc syntax, this function almost similar to putch( ).

Closing a file
16
Code –

fclose(fp);
fclose( ) function is used for closing an opened file. As an argument you must
provide a pointer of FILE type, which is currently pointing to a file.
Now you have understood all the three main operations on the file, Let’s use all
three in one C program – I’ll copy content of FILE1.C to FILE2.C
#include <stdio.h>
int main()
{
char ch;

/* Pointer for both the file*/


FILE *fpr, *fpw;
/* Opening file FILE1.C in “r” mode for reading */
fpr = fopen("FILE1.C", "r");

/* Ensure FILE1.C opened successfully*/


if (fpr == NULL)
{
puts("Input file is having issues while opening");
}

/* Opening file FILE2.C in “w” mode for writing*/


fpw= fopen("FILE2.C", "w");

/* Ensure FILE2.C opened successfully*/


if (fpw == NULL)
{
puts("Output file is having issues while opening");
}

/*Read & Write Logic*/


while(1)
{

17
ch = fgetc(fpr);
if (ch==EOF)
break;
else
fputc(ch, fpw);
}

/* Closing both the files */


fclose(fpr);
fclose(fpw);

return 0;
}

How to read/ write (I/O) Strings in Files – fgets


& fputs

Above we have seen how to read and write characters from/into files. Here we will
learn strings I/O from/into files. We have two functions to do that –

char *fgets(char *s, int rec_len, FILE *fpr)


Consider the example first –

#include <stdio.h>
int main()
{
FILE *fpr;
/*Char array to store strings */
char str[100];
/*Opening the file in "r" mode*/
fpr = fopen("FILER.TXT", "r");

/*Error handling for file open*/


if (fpr == NULL)

18
{
puts("Issue in opening the input file");
}

/*Loop for reading the file till end*/


while(1)
{
if(fgets(str, 10, fpr) ==NULL)
break;
else
printf("%s", str);
}
/*Closing the input file after reading*/
fclose(fpr);
return 0;
}
I have explained most of the operations in the example itself. The main thing I
wanna discuss now – Do you see fgets function in above example? Let’s talk about
it in detail –

It takes three arguments –


fgets(str, 10, fpr)
here str represents the string (array of char) in which you are storing the string
after reading it from file.
10 is the length of the string need to be read every time.
fpr is pointer to file, which is going to be read.

In general –
char *fgets(char *s, int rec_len, FILE *fpr)
s – Array of characters to store strings.
rec_len – Length of the input record.
fpr – Pointer to the input file.
Why I used if(fgets(str, 10, fpr)==NULL as a logic to determine end of the file?
In previous tutorial we have used ch==EOF to get to know the end of the file. Here

19
we have used this logic because fgets returns NULL when there is no more records
are available to be read.
int fputs ( const char * s, FILE * fpw );
Sample program –
#include <stdio.h>
int main()
{
FILE *fpw;

/*Char array to store strings */


char str[100];

/*Opening the file FILEW.TXT in “w” mode for writing*/


fpr = fopen("FILEW.TXT", "w");

/*Error handling for output file*/


if (fpw== NULL)
{
puts("Issue in opening the Output file");
}

printf("Enter your string:");

/*Stored the input string into array – str*/


gets(str);

/* Copied the content of str into file –


* FILEW.TXT using pointer – fpw*/
fputs(str, fpw);

/*Closing the Output file after successful writing*/


fclose(fpw);
return 0;
}
fputs takes two arguments –

20
fputs(str, fpw)
str – str represents the array, in which string is stored.
fpw – FILE pointer to the output file, in which record needs to be written.
In general –
int fputs ( const char * s, FILE * fpw );
char *s – Array of char.
FILE *fpw – Pointer (of FILE type) to the file, which is going to be written.
Point to note about fputs:
fputs by default doesn’t add new line after writing each record, in order to do that
manually – you can have the below statement after each write to the file.
fputs("\n", fpw);

FILE I/O for Binary files

So far, we have learnt file operations on text files, what if the files are binary
(such as .exe file). The above programs will not work for binary files, however
there is a minor change in handling Binary files. The main difference is the file
name & modes. Lets understand this with the help of an example –
Lets say I have two binary files bin1.exe & bin2.exe – I want to copy content of
bin1.exe to bin2.exe –
#include <stdio.h>
int main()
{
char ch;

/* Pointers for both binary files*/


FILE *fpbr, *fpbw;

/* Open for bin1.exe file in rb mode */


fpr = fopen("bin1.exe", "rb");

/* test logic for successful open*/


if (fpbr == NULL)
{

21
puts("Input Binary file is having issues while opening");
}

/* Opening file bin2.exe in “wb” mode for writing*/


fpbw= fopen("bin2.exe", "wb");

/* Ensure bin2.exe opened successfully*/


if (fpbw == NULL)
{
puts("Output binary file is having issues while opening");
}

/*Read & Write Logic for binary files*/


while(1)
{
ch = fgetc(fpbr);
if (ch==EOF)
break;
else
fputc(ch, fpbw);
}

/* Closing both the binary files */


fclose(fpbr);
fclose(fpbw);

return 0;
}

Switch case statements mostly used when we have number of options (or choices)
and we may need to perform a different task for each choice.
Structure of switch case would look like this –
switch (variable or an integer expression)
{

22
case constant:
//C code
;
case constant:
//C code
;
default:
//C code
;
}
Actual code would be like this –
int main()
{
int num=2;
switch(num+2)
{
case 1:
printf("Case1: Value is: %d", num);
case 2:
printf("Case1: Value is: %d", num);
case 3:
printf("Case1: Value is: %d", num);
default:
printf("Default: Value is: %d", num);
}
return 0;
}
Output:
Default: value is: 2
Explanation: In switch I gave an expression, you can give variable also. I gave
num+2, where num value is 2 and after addition the expression resulted 4. Since
there is no case defined with value 4 the default case got executed.
So what exactly a switch does?
It evaluates the value of expression or variable (based on whatever is given inside
switch braces), then based on the outcome it executes the corresponding case.

23
Twist in a story – Introducing Break statement

Before I discuss more about break statement, can you please guess the output of
below C program?

int main()
{
int i=2;
switch (i)
{
case 1:
printf("Case1 ");
case 2:

24
printf("Case2 ");
case 3:
printf("Case3 ");
case 4:
printf("Case4 ");
default:
printf("Default ");
}
return 0;
}
Output:
Case2 Case3 Case4 Default
Is that what you guessed? If yes then you can skip the below paragraph otherwise
read it carefully –
I passed a variable to switch, which had the value 2 so the control jumped to the
case 2, However since there are no such statements in the above program which
could break the flow. That’s the reason after case 2 program execution happens in
a flow and all subsequent cases and default statements got executed.

How to avoid such issues?


Above issue can be avoided using break statements in each of the cases. let’s
discuss it in detail.

Break statement

Break statements are useful when you want your program-flow to come out of the
switch body. Whenever a break statement is encountered in the switch body, the
execution flow would directly come out of the switch.

Example:
I’m taking the same above example but I will use break statements –
int main()
{
int i=2;
switch (i)

25
{
case 1:
printf("Case1 ");
break;
case 2:
printf("Case2 ");
break;
case 3:
printf("Case3 ");
break;
case 4:
printf("Case4 ");
break;
default:
printf("Default ");
}
return 0;
}
Output:
Case 2
Why didn’t I use break statement after default?
The control would itself come out of the switch after default so I didn’t use it,
however if you still want to use the break after default then you can use it, there
is no harm in doing that.

Few points about Switch Case

1) Case doesn’t always need to have order 1, 2, 3 and so on. It can have any
integer value after case keyword. Also, case doesn’t need to be in an ascending
order always, you can specify them in any order as per the need of the program.

2) You can also use characters in switch case. for example –

int main()
{

26
char ch='b';
switch (ch)
{
case 'd':
printf("CaseD ");
break;
case 'b':
printf("CaseB");
break;
case 'c':
printf("CaseC");
break;
case 'z':
printf("CaseZ ");
break;
default:
printf("Default ");
}
return 0;
}
Output:

CaseB
3) The expression provided in the switch should result in a constant value
otherwise it would not be valid.
For example:
Valid expressions for switch –
switch(1+2+23)
switch(1*2+3%4)
Invalid switch expressions –
switch(ab+cd)
switch(a+b+c)

27
Recursion is the process of repeating items in a self-similar way. In
programming languages, if a program allows you to call a function inside
the same function, then it is called a recursive call of the function.

void recursion() {

recursion(); /* function calls itself */

int main() {

recursion();

The C programming language supports recursion, i.e., a function to call


itself. But while using recursion, programmers need to be careful to
define an exit condition from the function, otherwise it will go into an
infinite loop.

Recursive functions are very useful to solve many mathematical


problems, such as calculating the factorial of a number, generating
Fibonacci series, etc.

Number Factorial
The following example calculates the factorial of a given number using a
recursive function −

#include <stdio.h>

int factorial(unsigned int i) {

if(i <= 1) {

return 1;

return i * factorial(i - 1);

int main() {

int i = 15;

printf("Factorial of %d is %d\n", i, factorial(i));

28
return 0;

When the above code is compiled and executed, it produces the following
result −

Factorial of 15 is 2004310016

Fibonacci Series
The following example generates the Fibonacci series for a given number
using a recursive function −

#include <stdio.h>

int fibonaci(int i) {

if(i == 0) {

return 0;

if(i == 1) {

return 1;

return fibonaci(i-1) + fibonaci(i-2);

int main() {

int i;

for (i = 0; i < 10; i++) {

printf("%d\t\n", fibonaci(i));

return 0;

29
The last chapter explained the standard input and output devices handled
by C programming language. This chapter cover how C programmers can
create, open, close text or binary files for their data storage.

A file represents a sequence of bytes, regardless of it being a text file or


a binary file. C programming language provides access on high level
functions as well as low level (OS level) calls to handle file on your
storage devices. This chapter will take you through the important calls
for file management.

Opening Files
You can use the fopen( ) function to create a new file or to open an
existing file. This call will initialize an object of the type FILE, which
contains all the information necessary to control the stream. The
prototype of this function call is as follows −

FILE *fopen( const char * filename, const char * mode );

Here, filename is a string literal, which you will use to name your file,
and access mode can have one of the following values −

Mode Description

R Opens an existing text file for reading purpose.

W Opens a text file for writing.

If it does not exist, then a new file is created.

Here your program will start writing content

from the beginning of the file.

a Opens a text file for writing in appending mode.

If it does not exist, then a new file is created.

Here your program will start appending content in

30
the existing file content.

r+ Opens a text file for both reading and writing.

w+ Opens a text file for both reading and writing.

It first truncates the file to zero length if it exists,

otherwise creates a file if it does not exist.

a+ Opens a text file for both reading and writing.

It creates the file if it does not exist.

The reading will start from the beginning but writing can only be
appended.

If you are going to handle binary files, then you will use following access
modes instead of the above mentioned ones −

"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"

Closing a File
To close a file, use the fclose( ) function. The prototype of this function is

int fclose( FILE *fp );

The fclose(-) function returns zero on success, or EOF if there is an


error in closing the file. This function actually flushes any data still
pending in the buffer to the file, closes the file, and releases any memory
used for the file. The EOF is a constant defined in the header file stdio.h.

There are various functions provided by C standard library to read and


write a file, character by character, or in the form of a fixed length
string.

Writing a File
Following is the simplest function to write individual characters to a
stream −

31
int fputc( int c, FILE *fp );

The function fputc() writes the character value of the argument c to the


output stream referenced by fp. It returns the written character written
on success otherwise EOF if there is an error. You can use the following
functions to write a null-terminated string to a stream −

int fputs( const char *s, FILE *fp );

The function fputs() writes the string s to the output stream referenced


by fp. It returns a non-negative value on success, otherwise EOF is
returned in case of any error. You can use int fprintf(FILE *fp,const
char *format, ...)function as well to write a string into a file. Try the
following example.

Make sure you have /tmp directory available. If it is not, then before


proceeding, you must create this directory on your machine.

#include <stdio.h>

main() {

FILE *fp;

fp = fopen("/tmp/test.txt", "w+");

fprintf(fp, "This is testing for fprintf...\n");

fputs("This is testing for fputs...\n", fp);

fclose(fp);

When the above code is compiled and executed, it creates a new


file test.txt in /tmp directory and writes two lines using two different
functions. Let us read this file in the next section.

Reading a File
Given below is the simplest function to read a single character from a file

int fgetc( FILE * fp );

The fgetc() function reads a character from the input file referenced by


fp. The return value is the character read, or in case of any error, it

32
returns EOF. The following function allows to read a string from a stream

char *fgets( char *buf, int n, FILE *fp );

The functions fgets() reads up to n-1 characters from the input stream


referenced by fp. It copies the read string into the buffer buf, appending
a nullcharacter to terminate the string.

If this function encounters a newline character '\n' or the end of the file
EOF before they have read the maximum number of characters, then it
returns only the characters read up to that point including the new line
character. You can also use int fscanf(FILE *fp, const char
*format, ...) function to read strings from a file, but it stops reading
after encountering the first space character.

#include <stdio.h>

main() {

FILE *fp;

char buff[255];

fp = fopen("/tmp/test.txt", "r");

fscanf(fp, "%s", buff);

printf("1 : %s\n", buff );

fgets(buff, 255, (FILE*)fp);

printf("2: %s\n", buff );

fgets(buff, 255, (FILE*)fp);

printf("3: %s\n", buff );

fclose(fp);

When the above code is compiled and executed, it reads the file created
in the previous section and produces the following result −

33
1 : This
2: is testing for fprintf...

3: This is testing for fputs...

Let's see a little more in detail about what happened here.


First, fscanf() read just This because after that, it encountered a space,
second call is for fgets()which reads the remaining line till it
encountered end of line. Finally, the last callfgets() reads the second
line completely.

34

You might also like