Вы находитесь на странице: 1из 60

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);

1
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];

/*Counter variables for the loop*/


int i, j;

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


{
for(j=0;j<=4;j++)
{

2
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};

3
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*/
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 }

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 –

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

6
Pointers & 2D array

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.

7
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;
}

8
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 –

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.

9
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 inmain() 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.

10
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.
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.

11
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 –

12
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;

/* function return type is integer so I


should return some
integer value */
return sum
}

int main()

13
{
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");

14
printf("How are you?");
/* there is no return statement inside this
function, since its
* return type is void */
}

int main()
{
/*calling function*/
introduction();
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.

15
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()
{

16

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

}
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 –

17
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;
}

18
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()
{

19
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 –
int main( )
{
int num1 = 35, num2 = 45 ;

20
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:

21
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 –
a) Creating a new file
b) Writing into a file
c) Opening an existing file
d) Reading a file
e) Closing a file

22
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);

23
}
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

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;

24
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

25
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.
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

26
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

27
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
* 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

28
/*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
*/

29
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

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.

30
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*/

31
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)
{
ch = fgetc(fpr);
if (ch==EOF)
break;
else
fputc(ch, fpw);
}

/* Closing both the files */


fclose(fpr);
fclose(fpw);

32
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];

33
/*Opening the file in "r" mode*/
fpr = fopen("FILER.TXT", "r");

/*Error handling for file open*/


if (fpr == NULL)
{
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

34
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 we have used
this logic because fgets returns NULL when there
is no more records are available to be read.

35
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:");

36
/*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 –
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.

37
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()

38
{
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)
{
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)
{

39
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;
}

40
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)
{
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:

41
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.

42
43
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:
printf("Case2 ");
case 3:
printf("Case3 ");
case 4:
printf("Case4 ");
default:
printf("Default ");
}
return 0;

44
}
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.

45
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)
{
case 1:
printf("Case1 ");
break;
case 2:
printf("Case2 ");
break;
case 3:
printf("Case3 ");
break;
case 4:
printf("Case4 ");

46
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.

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

int main()
{
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 ");
}

48
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)

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.

49
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 −

50
#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));

return 0;

When the above code is compiled and


executed, it produces the following result −

Factorial of 15 is 2004310016

Fibonacci Series

51
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++) {

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

return 0;

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
53
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 n


Here your program will start writing content from the be

a Opens a text file for writing in appending mode. If it doe


new file is created. Here your program will start appendi
existing file content.

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

w+ Opens a text file for both reading and writing. It first tru
zero length if it exists, otherwise creates a file if it does n

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


not exist. The reading will start from the beginning but w
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

55
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 −

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
56
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

57
/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 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
58
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 );

59
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 −

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.

60

Вам также может понравиться