Wednesday, 8 January 2014

C Programming Language Tutorial XVII – Commandline Argument

Command Line Arguments
Parameters pass to a program by command prompt treat as command line arguments. The parameters are generally used to pass some useful information to the program. An argument is the information that follows the program name on the command line of the operating system.
Till now we have used the main method in a very limited form. main() method can take arguments just like any other function. main() can take two arguments called argc and argv, and the information contained in the command line arguments is passed to the main method through this arguments, when main method is called by the system for execution.
main(int argc, char *argv[])
The argc argument holds the number of arguments on the command line and is an integer. The value of argc is at least 1 because the name of the program qualifies as the first argument.
The argv parameter is a pointer to an array of character pointers.
When a copy command of DOS is used, the statement given is : copy file1 file2.
Like above statement you can also create your own command by using commandline argument.
Following program is to print and count number of arguments pass to main() function.
#include<stdio.h>
#include<conio.h>
void main(int argc,char *argv[])   //arguments for main()
{
 int cnt;
 clrscr();
 printf("Total arguments = %d\n",argc);   //It counts and print  no. of arguments
 for(cnt=0;cnt<argc;cnt++)
 {
  printf("argv[%d] = %s\n",cnt,argv[cnt]);
 }
 getch();
}
Whenever you complied and execute this program then it will display output as follows:
Total arguments = 1
argv[0] = CARGS.EXE
By default, the programs name is a first argument. Here the above program is saved by cargs.c name. To pass arguments from command prompt you have to run this program on DOS.
If you have a Turboc then follow the steps:
  1. File->DOS Shell
  2. C:\TCC>cargs.exe Apple Mango
  3. Total arguments = 3
argv[0] = C:\TCC\CARGS.EXE
argv[1] = Apple
argv[2] = Mango

C Programming Language Tutorial XVI – File Handling (fopen, fclose, FILE, getc, putc, fgets, fputs, fprintf, fscanf, rewind, fwrite, fread, eof)

File Handling
The essential things of computing are saving and retrieving the data. Everyone who uses the computer needs to save and retrieve lot many things. The key to saving and retrieving the information using computer is files.
Information stored in the device in the form of a data file. File allows us to store information permanently, and to access and alter information whenever necessary.
There are two different types of file
  1. Stream oriented data files – These file also called as standard files.
  2. System oriented data files – These files also called as low level files.
Stream oriented files can be divided into two categories
§  In the first category, data files comprising consecutive characters. These characters can be interpreted as individual data items.
§  The second category of stream oriented data files, often referred to as unformatted data files, organizes data into blocks containing contiguous bytes of information.
File I/O operations in C are carried out by library functions.
The different operations that can be carried out on a file are as follows
§ Creation of new file.
§ Opening new file.
§ Reading from file.
§ Writing to a file.
§ Going through the file contents.
§ Closing a file.
Terms and conditions
§ Always include file stdio.h.
§ Declare file pointer by using type FILE.
§ After declaration file pointer should be initialize by file open function.
§ After performing single operation always close file.
How to declare file pointer
FILE *filepointer;
Initialization
filepointer = fopen(“filename”,”mode”);
Different modes of file
a
Appending mode
a+
Appending and reading
r
Read only
r+
Reading and writing
w
Write only
w+
Writing and reading
Functions for reading from a file
getc()
Reads a character from a file that has been opened in read mode.
fgets()
Reads a string from file.
getw()
Reads an integer from a file.
fscanf()
Reads formatted input from a file.
Functions for writing to a file
putc()
Writes a character to a file that has been opened in write or append mode.
fputs()
Writes a string to a file.
putw()
Writes an integer to a file.
fprintf()
Writes formatted output to a file.
Files and Binary I/O
All above functions only work with text files. But if we want to handle binary files then we have to use different set of functions.
Text files
A text file is a generic description of a computer file. The information is represented in terms of character set.  These files are in human readable forms.
// prog to write a single character to file
#include<stdio.h>
#include<conio.h>
void main()
{
  FILE *fp;  //Declaration of file pointer
  char ch;
  clrscr();
  fp=fopen("c:\\abc.txt","w");    //File open in write mode
    printf("Enter any character to store in file \n");
    flushall();
    scanf("%c",&ch); //scan character from user
    putc(ch,fp); // store in file
   fclose(fp);
    printf("\nFile created successfully...");
getch();
}
Output:
Enter any character to store in file
$
File created successfully...
// prog to read single character from file
#include<stdio.h>
#include<conio.h>
void main()
{
  FILE *fp;
  char ch';
  clrscr();
  //open file in read mode
  fp=fopen("c:\\abc.txt","r");   //File open in read mode
  printf("\nCharacter from file: ");
  ch=getc(fp);   //Reads single character from file
  printf("%c",ch);
  fclose(fp);
getch();
}
Output:
Character from file: $
In following program two operations are merged. Here you should enter single character but you can be entering one by one character as well as you can read one by one character from a single file. How it is possible? Look at following program.
// prog to write & read a single character from file
#include<stdio.h>
#include<conio.h>
void main()
{
  FILE *fp;
  char ch,ans='y';  //’y’ value stored in variable ans because initially while loop must be true.
  clrscr();
 
  fp=fopen("c:\\abc.txt","w");
  while(ans=='y')
  {
    printf("Enter any character to store in file \n");
    flushall();             //this function is use to clean buffer (temporarily memory storage)
    scanf("%c",&ch);
   
    putc(ch,fp); // store in file
   
printf("Do you want to enter more character?\n"); 
    flushall();
    scanf("%c",&ans);   //Ask user to store more character to file if ‘y’ is entered then only loop get reapeate
  }
    fclose(fp);
  fp=fopen("c:\\abc.txt","r");         //open file in read mode
  printf("character from file....\n");
  while((ch=getc(fp))!=EOF)          //Read single character at a time till end of file
    {
      printf("%c",ch);
    }
  fclose(fp);
getch();
}
Output:
Enter any character to store in file
M
Do you want to enter more character?
y
Enter any character to store in file
u
Do you want to enter more character?
y
Enter any character to store in file
m
Do you want to enter more character?
y
Enter any character to store in file
b
Do you want to enter more character?
y
Enter any character to store in file
a
Do you want to enter more character?
y
Enter any character to store in file
i
Do you want to enter more character?
n
character from file....
Mumbai
In following example instead of fixed path filename variable is used. In this case file compulsory created in TCC folder.
//copy contents of source file into target file
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
 FILE *fp,*fc;
 char sfname[12],tfname[12],ch;                         //source and target files name are declared
 clrscr();
 printf("Enter source filename\n");
 gets(sfname);
 printf("Enter target filename\n");
 gets(tfname);
 fp=fopen(sfname,"r");               //Open source file in read mode
 if(fp == NULL)              //If fp returns NULL then file not exists
 {
  printf("File does not exists...\n");
  getch();
  exit(0);            //After showing above statement program will close.
 }
 else
 {
  fc = fopen(tfname,"w");           //Open target file in write only mode
  while((ch=getc(fp))!=EOF)
  {
   putc(ch,fc);    //fp reads character from source file and fc writes character to target file till end of source file
  }
  printf("File is copied successfully...\n");
 }
 fcloseall();  //close both files
 fc=fopen(tfname,"r");    //To check whether copied done successfully or not, open target file in read mode
  printf("Copied contents of file...\n");
  while((ch=getc(fc))!=EOF)        //Read characters
  {
   printf("%c",ch);
  }
  fclose(fc);
  getch();
 }
Following program is to open file in read mode and count no. of lines, semicolons and length of file. While execution following program you can use source file as ‘C’ or C++ file.
//Program to perform counting operations
#include<stdio.h>
#include<conio.h>
void main()
{
 FILE *fp;
 char sfname[12],ch;
 int line=0,semi=0,len=0;
 clrscr();
 printf("Enter filename for counting\n");
 gets(sfname);
 fp=fopen(sfname,"r");
 if(fp == NULL)
 {
  printf("File does not exists...\n");
  getch();
  exit(0);
 }
 else
 {
  while((ch=getc(fp))!=EOF)
  {
  len++;             //When ch is found then at every time len get increment
  if(ch == '\n')    //To check is ch is a new line
  {
   line++;
  }
  if(ch == ';') //To check is ch is a semicolon
  {
   semi++;
  }
 }
}
  fclose(fp);
  printf("Total length of file    => %d\n",len);
  printf("Total line           => %d\n",line);
  printf("Total no. of semicolons  => %d\n",semi);
  getch();
 }
Output:
Enter filename for counting
file1.c
Total length of file    => 411
Total line      => 27
Total no. of semicolons  => 14
You can count more things like no. of curly brackets, no. of spaces and no. of upper case character etc.
String Input/Output functions:
In addition to fgetc() and fputc(), C supports the related functions fputs() and fgets(), which write and read character strings to and from disk file.
rewind()
whenever we open file in w+ mode then position of pointer get changed. After writing records you need to read records so to reset pointer at beginning position rewind() function is very useful.
The rewind() function resets the file position indicator to the beginning of the file.
It takes the file pointer to the file, which is to be rewound as its argument.
//prog to write & read string from file
#include<stdio.h>
#include<conio.h>
void main()
{
FILE *fp;
char str[15];
int i,n;
clrscr();
fp=fopen("c:\\TCC\\string.txt","w+");       //Write and read mode
printf("Enter how many strings\n");
scanf("%d",&n);
printf("Enter %d strings\n",n);
for(i=0;i<n;i++)
{
printf("Enter any string\n");
flushall();
gets(str);
//to write str into file
fputs(str,fp);
putc('\n',fp);      //After storing string new line is stored
}
rewind(fp);        //To set pointer at beginning position for reading string
printf("Content of file\n");
for(i=0;i<n;i++)
{
fgets(str,15,fp);             //fgets() has arguments as string variable, size of string and file pointer
printf("%s",str);
}
fclose(fp);
getch();
}
Output:
Enter how many strings
3
Enter 3 strings
Enter any string
Delhi
Enter any string
London
Enter any string
Mumbai
Content of file
Delhi
London
Mumbai
printf() and scanf() Functions
These functions are similar to printf() and scanf() except that they
operate with files.
The prototypes of fprintf() and fscanf() are:
            fprintf(fp,format specifier , list of data members…);
            fscanf(fp, format specifier, address of data members…);
//structure by using fprintf & fscanf function
#include<stdio.h>
#include<conio.h>
#define p printf             //p defined as a short key for printf()
#define s scanf             //s defined as a short key for scan()
struct Book
{
int bno;
char name[10];
int price;
}b;        //b variable does not have a size because at a time you are storing single record to a file
void main()
{
FILE *fp;
char ans='y';
clrscr();
fp=fopen("c:\\TCC\\booklist.txt","a");      //Open file in append mode
while(ans=='y')
{
p("Enter bookno, name & price\n");
s("%d %s %d",&b.bno,&b.name,&b.price);
fprintf(fp,"%d %s %d\n",b.bno,b.name,b.price); //write records to file
p("Do you have more records? (y/n)\n");
flushall();
s("%c",&ans);
}
fclose(fp);
fp=fopen("c:\\TCC\\booklist.txt","r");
printf("Records from file are\n");
while((fscanf(fp,"%d %s %d\n",&b.bno,&b.name,&b.price))!=EOF)
{
p("%d\t %s\t %d\n",b.bno,b.name,b.price);
}
fclose(fp);
getch();
}
Output:
Enter bookno, name & price
101
Flash
234
Do you have more records? (y/n)
y
Enter bookno, name & price
102
Oracle
420
Do you have more records? (y/n)
n
Records from file are
101      Flash   234
102      Oracle  420
Binary Files
The information must be interpreted by a program. These file are not in human readable form.
Information encoded in the binary format.
To handle binary I/O, C provides two functions, namely fwrite() and fread().
§ fwrite() function is used to write a block of data to file in a binary form.
§ fread() causes data to be read from the disk file and placed in an object.
fwrite(&object, sizeofobject,no.ofobjects,file-pointer);
§ The first argument is address of structure variable.
§ The second argument is the size of the structure variable in bytes.
§ The third argument is the number of such arguments we want to write at one time to the file.
§ The last argument is the pointer to a file.
Random Access to Files
Whenever we create and initialize file pointer, then it always starts working from beginning of the file, which is commonly referred sequential access to a file. All the functions we have discussed are useful for writing or reading the data sequentially.
However, in many applications we may need to access particular location in a file or we may need to access particular record within the file, which is commonly referred as random access to a file. This task carried out with the help of library functions.
ftell()
Returns the position of the file pointer within the file
long ftell(file-pointer)
rewind()
Places the file pointer at the beginning of the file.
void ftell(file-pointer)
fseek()
Moves the file pointer to a desired location.
-
int fseek(file-pointer, long offset, int origin);
fseek() set file pointer to offset bytes from the position indicated by origin.
Origin
File Location
SEEK_SET or 0
Beginning of file
SEEK_CUR or 1
Current file pointer position
SEEK_END or 2
End of file
//structure by using fwrite() & fread() function
#include<stdio.h>
#include<conio.h>
#define p printf
#define s scanf
struct Book
{
int bno;
char name[10];
int price;
};
struct Book b;
void main()
{
FILE *fp;
char ans='y';
int tbno,flag;
clrscr();
fp=fopen("c:\\filebook.txt","ab");                        //Open file in append mode in binary format
while(ans=='y')
{
p("Enter bookno, name & price\n");
s("%d %s %d",&b.bno,&b.name,&b.price);
fwrite(&b,sizeof(b),1,fp);
p("you have more records? (y/n)\n");
flushall();
s("%c",&ans);
}
fclose(fp);
fp=fopen("c:\\filebook.txt","rb");
printf("Records are\n");
while((fread(&b,sizeof(b),1,fp)))
{
p("%d\t %s\t %d\n",b.bno,b.name,b.price);
}
fseek(fp,0,SEEK_SET); //After reading all records pointer is at EOF. So set it to BOF by using fseek() method for sequential searching operation.
printf("Enter book no for search\n");
scanf("%d",&tbno);
while((fread(&b,sizeof(b),1,fp)))
{
if(tbno == b.bno)
{
flag=1;              //If record exists set falg=1 and break a loop
p("Record found...\n");
p("%d\t %s\t %d\n",b.bno,b.name,b.price);
break;
}
else
flag=0;  //If record does not exists then flag is always zero
}
if(flag==0)
printf("Record not found....\n");
fclose(fp);
getch();
}
Output:
Enter bookno, name & price
1
Java
340
you have more records? (y/n)
y
Enter bookno, name & price
2
VB6
200
you have more records? (y/n)
n
Records are
1        Java    340
2        VB6     200
Enter book no for search
2
Record found...
2        VB6     200
Let us create a big program that handles all types of database operations. You can say that it is a mini project of ‘C’.
#include<stdio.h>
#include<conio.h>
#define p printf
#define s scanf
struct Bank
{
int acno;
char acname[10];
char type[10];
int bal;
}b;
void main()
{
FILE *fp,*ft;
int choice,flag,no,amt;
char ans='y',trans;
clrscr();
while(1)             //Infinite loop
{
p("1. Open new account\n");
p("2. List all account\n");
p("3. Search accont details\n");
p("4. Deposit\n");
p("5. Withdraw\n");
p("6. Exit\n");
p("Enter your choice\n");
s("%d",&choice);
switch(choice)
{
case 1:
{
fp=fopen("c:\\bank1.txt","ab+");
ans='y';
while(ans=='y')
{
p("Enter account no\n");
s("%d",&b.acno);
p("Enter account name\n");
s("%s",&b.acname);
p("Enter account type\n");
flushall();
s("%s",&b.type);
p("Enter account amount\n");
s("%d",&b.bal);
fwrite(&b,1,sizeof(b),fp);
p("Do yo want to add more records?\n");
flushall();
s("%c",&ans);
}
fclose(fp);
break;
}
case 2:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Account no.\t Name\t Actype\t Bal\n");
p("******************************************\n");
while((fread(&b,1,sizeof(b),fp))!=eof())
{
flushall();
p("%3d\t %-10s %-10s %3d\n",b.acno,b.acname,b.type,b.bal);
}
fclose(fp);
break;
}
case 3:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Enter account no for search\n");
s("%d",&no);
while((fread(&b,1,sizeof(b),fp))!=eof())
{
if(no==b.acno)
{
flag=1;
p("Record found........\n");
p("%3d\t %-10s\t %-10s\t %3d\n",b.acno,b.acname,b.type,b.bal);
break;
}
else
{
flag=0;
}
}
fclose(fp);
if(flag==0)
{
p("Record not found.......\n");
}
break;
}
case 4:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Enter account no for transaction\n");
s("%d",&no);
while((fread(&b,1,sizeof(b),fp))!=eof())
{
if(no==b.acno)  //For transaction you have to search record to set pointer at given location
{
flag=1;
p("Record found........\n");
p("%3d\t %-10s\t %-10s\t %3d\n",b.acno,b.acname,b.type,b.bal);
p("Enter amount for deposition\n");
s("%d",&amt);
b.bal=b.bal+amt;
fseek(fp,-24,SEEK_CUR);          //To set file pointer at current searched location. -24 is used because record size is fixed as 24 bytes that depends upon data members of structure.
p("Balance is debited....\n");
fwrite(&b,1,sizeof(b),ft);             //Rewrite the updated record
break;
}
else
{
flag=0;
}
}
fclose(fp);
if(flag==0)
p("Record not found......\n");
break;
}
case 5:
{
fp=fopen("c:\\bank1.txt","rb+");
p("Enter account no for transaction\n");
s("%d",&no);
while((fread(&b,1,sizeof(b),fp))!=eof())
{
if(no==b.acno)
{
flag=1;
p("Record found........\n");
p("%3d\t %-10s\t %-10s\t %3d\n",b.acno,b.acname,b.type,b.bal);
p("Enter amount for withdraw\n");
s("%d",&amt);
if(amt>a.bal)
{
b.bal=b.bal-amt;
fseek(fp,-24,SEEK_CUR);
p("Balance is credited....\n");
fwrite(&b,1,sizeof(b),ft);
}
else
printf(“\nInsufficient balance…”);
break;
}
else
{
flag=0;
}
}
fclose(fp);
if(flag==0)
p("Record not found......\n");
break;
}
case 6:
{
exit(0);
}
getch();
}
}
}
When you create this program then write only  1, 2 and 6 cases first then run it successfully after that insert one by one case, check it by executing the program. Do not write whole code at a time otherwise it is very difficult to type and execute. This program will give you a big output.