Images

Advance C - PART I


Advance C
C is a general-purpose, block structuredprocedural,imperative computer programming language developed in1972 by Dennis Ritchie at the Bell Telephone Laboratoriesfor use with the Unix operating system. It has since spread to many other platforms. Although C was designed as a system implementation language, it is also widely used for applications. C has also greatly influenced many other popular languages,especially C++, which was originally designed as an extension to C.
Despite its popularity, C has been widely criticized. Such criticisms fall into two broad classes: desirable operations that are too hard to achieve using unadorned C, and undesirable operations that are too easy to accidentally invoke while using C. Putting this another way, the safe, effective use of C requires more programmer skillexperienceeffort, and attention to detail than is required for some other programming languages.
This Tutorial Covers a lot of Advance C concept(such as Graphic Under C, TSRs, Drivers, and Kernal basics). As said earlier, effective use of C requires more programmer skill, experience, effort, and attention to detail than is required for some other programming languages, so be careful while using examples given and/or doing some R&D based on the code samples provided.



Introduction to Advanced Concepts of C
Introduction
The programming language C was originally developed by Dennis Ritchie of Bell Laboratories. C Language was designed to run on a PDP-11 with a UNIX operating system. Although C language was originally intended to run under UNIX, there has been a great interest in running it under the MS-DOS operating system on the IBM PC and compatibles. C programming language is an excellent language for this environment because of the simplicity of expression, the compactness of the code, and the wide range of applicability. Also, due to the simplicity and ease of writing a C compiler, it is usually the first high level language available on any new computer, including microcomputers, minicomputers, and mainframes.
C programming language is specifically created in order to allow the programmer access to almost all of the machine's internals - registers, I/O slots and absolute addresses. However, at the same time, C language allows for as much data hiding and programme text modularisation as is needed to allow very complex multi-programmer projects to be constructed in an organised and timely fashion. During the early 1960s computer Operating Systems started to become very much more complex with the introduction of multi-terminal and multi-process capabilities. Prior to this time Operating Systems had been carefully and laboriously crafted using assembler codes, and many programming teams realised that in order to have a working o/s in anything like a reasonable time this was now longer economically feasible.
C is not the best beginning language because it is somewhat cryptic in nature. It allows the programmer a wide range of operations from high level down to a very low level, approaching the level of assembly language. There seems to be no limit to the flexibility available.
Where we can use C?
Virtually there is no limit on what you do with C. But, remember one thing, C is not everyones language. By “everyone”, I mean, C is not a language that is easy to bigin with, you may feel uncomfortable in the beginning. C has rigid set of rules, C is not a forgiving language. But, when it comes speed and performance, C is far far ahead from it's competitors & companions. C is an excellent language for developing applications where speed & performance comes before anything else.
C programs has execution speed that is somewhat equal to assembly language, yet they are much easier to develope, debug and maintain.
C is very useful for creating applications for embedded deviceshardware programming, device driver development, scientific applications, OS & Kernal development.
C is best suited for following types of applications:
  1. Hardware Programming
  2. Device Drivers
  3. Game Development
  4. Operating System Modules
  5. Scientific Application
  6. Embedded Applications

Introduction to Advanced Concepts of C
Prerequisite
This tutorial is not a “Beginners Guide to C”, this tutorial is meant for those who has basic knowledge of C language and it's concepts. It deal with advanced concepts of C language such as File HandlingGraphics under C, and Low level programming.
If you are new to the world of programming, especially C, this tutorial is not for you. This tutorial does not deal with basics of C language, and if you want to begin with or brush up your basic skills of C language, then please read our C tutorial athttp://education.ebizel.com.
What you should already know?
This tutorial assumes that, you, as a reader have the basic knowledge of C language. That you are familiar with C variablesdata types, basic knowledge of pointers etc.
Prerequisites :
  1. You should be familiar with basic concepts, syntax etc of C language.
  2. Familiarity with C standard input and output routines and their syntax.
  3. Knowledge of C control & decision making structure.
  4. Basic knowledge of pointers.
Core Warning:
Chapter 4 & 5 deal with low level functions, such as, Memory management, Device drivers, TSR and disk management, VDU and Video Memory etc. These chapters contains example that are used to demonstrate how C deals with them. Please DO NOT TRY TO RUN/EXECUTEthose examples on YOUR SYSTEM. You may end up corrupting your Hard DriveKeyboard,VDU or other such devices.
Despite this warning if you try to run those examples on your system, then in such caseseBIZ.com shall not be held responsible for any kind damage caused by running the examples on your system. You can not blame me or eBIZ education team or eBIZ.com Pvt Ltd for your losses done by running these example on your system, so please do not run them.

File Handling using C
Introduction to File Handling
Files are places for reading data from or writing data to. This includes disk files and it includes devices such as the printer or the monitor of a computer. C treats all information which enters or leaves a program as though it were a stream of bytes: a file. The most commonly used file streams are stdin (the keyboard) and stdout (the screen), but more sophisticated programs need to be able to read or write to files which are found on a disk or to the printer etc.
Although C does not have any built-in method of performing file I/O, the C standard library contains a very rich set of I/O functions providing an efficient, powerful and flexible approach. We will cover the ANSI file system but it must be mentioned that a second file system based upon the original UNIX system is also used but not covered on this course.
A very important concept in C is the stream. In C, the stream is a common, logical interface to the various devices that comprise the computer. In its most common form, a stream is a logical interface to a file. As C defines the term "file", it can refer to a disk file, the screen, the keyboard, a port, a file on tape, and so on. Although files differ in form and capabilities, all streams are the same. The stream provides a consistent interface and to the programmer one hardware device will look much like another.
C provides two levels of file handling; these can be called high level and low level. High level files are all treated as text files. In fact, the data which go into the files are exactly what would be seen on the screen, character by character, except that they are stored in a file instead. This is true whether a file is meant to store characters, integers, floating point types. Any file, which is written to by high level file handling functions, ends up as a text file which could be edited by a text editor.
High level text files are also read back as character files, in the same way that input is acquired from the keyboard. This all means that high level file functions are identical in concept to keyboard/screen input/output.
The alternative to these high level functions is obviously low level functions. These are more efficient, in principle, at filing data as they can store data in large lumps, in raw memory format, without converting to text files first. Low level input/output functions have the disadvantage that they are less `programmer friendly' than the high level ones, but they are likely to work faster.

File Handling using C
Opening and Closing a File
Opening a file
In order to use files we have to learn about File I/O i.e. how to write information to a file and how to read information from a file.
We will see that file I/O is almost identical to the terminal I/O that we have being using so far.
The primary difference between manipulating files and doing terminal I/O is that we must specify in our programs which files we wish to use.
As you know, you can have many files on your disk. If you wish to use a file in your programs, then you must specify which file or files you wish to use.
Specifying the file you wish to use is referred to as opening the file.
When you open a file you must also specify what you wish to do with it i.e. Read from the file, Write to the file, or both.Because you may use a number of different files in your program, you must specify when reading or writing which file you wish to use. This is accomplished by using a variable called a file pointer.
Every file you open has its own file pointer variable. When you wish to write to a file you specify the file by using its file pointer variable.
You declare these file pointer variables as follows:
FILE *fopen(), *fp1, *fp2, *fp3;
The file <stdio.h> contains declarations for the Standard I/O library and should always be included at the very beginning of C programs using files.
Constants such as FILEEOF and NULL are defined in <stdio.h>.
You should note that a file pointer is simply a variable like an integer or character. To open a file and associate it with a stream, use fopen().
Its prototype is shown here:
FILE *fopen(char *fname,char *mode);
The fopen() function, like all the file-system functions, uses the header stdio.h . The name of the file to open is pointed to by fname (must be a valid name).
The string pointed at for mode determines how the file may be accesed as shown:
Mode Meaning
rOpen a text file for reading
wCreate a text file for writing
aAppend to a text file
rbOpen a binary file for reading
wbOpen a binary file for writing
abAppend to a binary file
r+Open a text file for read/write
w+Create a text file for read/write
a+Append or create a text file for read/write
r+bOpen a binary file for read/write
w+bCreate a binary file for read/write
a+bAppend a binary file for read/write
If the open operation is successful, fopen() returns a valid file pointer. The type FILE is defined in stdio.h. It is a structure that holds various kinds of information about the file, such as size.The file pointer will be used with all other functions that operate on the file and it must never be altered or the object it points to. If fopen() fails it returns a NULL pointerso this must always be checked for when opening a file.
For example:
FILE *fp;

if ((fp = fopen("myfile", "r")) ==NULL){
  printf("Error opening file\n");
  exit(1);
}
Closing a File
To close a file, use fclose(), whose prototype is:
int fclose(FILE *fp);
The fclose() function closes the file associated with fp, which must be a valid file pointer previously obtained using fopen(), and disassociates the stream from the file. The fclose()function returns 0 if successful and EOF (end of file) if an error occurs.
The function fclose is used to close the file i.e. indicate that we are finished processing this file.
We could reuse the file pointer fp by opening another file.
Example:
Simple word count program
#include <stdio.h>

int main()
{
          /*Variable Declaration*/
          /* The File Pointer*/
          FILE *fp;
          int no_line,no_space,no_tabs,no_char;
          char ch;
          /*File to open*/
          char file[]={"wordCount.c"};
          no_line=0;
          no_space=0;
          no_tabs=0;
          no_char=0;
       
          /*Open the file using fopen method in read-only mode*/
          fp=fopen(file,"r");
          if(fp==NULL)
          {
                   printf("\nUnable to Open the file %s for reading\n",file);
                   exit(0);
          }
          else
          {
                   while(1)
                   {
                             ch=fgetc(fp);
                             if(ch==EOF)
                                      break;
                             no_char++;
                             if(ch=='\n')
                                      no_line++;
                             if(ch=='\t')
                                      no_tabs++;
                             if(ch==' ') 
                                      no_space++;
                   }
          }
          fclose(fp);
          printf("\n****************************************************\n");
          printf("****************FILE STATISTIC***********************\n");
          printf("File Name                      :         %s\n",file);
          printf("No of Character(s) in file        :         %d\n",no_char);
          printf("No of Tab(s) in file                 :         %d\n",no_tabs);
          printf("No of Blank Space(s) in file     :         %d\n",no_space);
          printf("No of Line(s) in file                 :         %d\n",no_line);
          printf("****************************************************\n");
          printf("****************************************************\n");

return 0;
}
Compiling and Running the program:
Compiling and Running on Windows(Turbo C)
To Compilepress ALT+F9
To Executepress Ctrl+F9
Compiling and running on Linux (Using GCC)
To Compile:
gcc <file.c> -o <object>
          i.e.
          gcc wordCount.c -o wordCount
To Execute:
./<object>
          i.e.
          ./wordCount
Output:

File Handling using C
Reading File Content
The Standard I/O Library provides similar routines for file I/O to those used for standard I/O.
Once the file has been opened for reading using fopen( ), as we have seen the file's contents are brought into memory (partly or wholly) and a pointer points to the very first character. To read the file's contents from memory there exists a function called fgetc( ). This has been used in our sample program through,
ch = fgetc ( fp ) ;
fgetc( ) reads the character from current pointer position, advances the pointer position so that it now points to the next character, and returns the character that is read, which we collected in the variable ch. Note that once the file has been opened, we no longer refer to the file by its name, but through the file pointer fp.
We have used the function fgetc( ) within an indefinite while loop. There has to be a way to break out of this while. When shall we break out... the moment we reach the end of file. But what is end of file? End of file is signified by a special character, whose ascii value is 26. This character is inserted beyond the last character in the file, when it is created. This character can also be generated from the keyboard by typing ctrl Z.
While reading from the file, when fgetc( ) encounters this special character, instead of returning the character that it has read, it returns the macro EOF. The EOF macro has been defined in the file "stdio.h". In place of the function fgetc( ) we could have as well used the macro getc( ) with the same effect.
The routine getc(fp) is similar to getchar()
and putc(c,fp) is similar to putchar(c).
Thus the statement
c = getc(fp);
reads the next character from the file referenced by fp and the statement
putc(c,fp);
writes the character c into file referenced by fp.
Example:
#include<stdio.h>

int main()
{
            FILE *fp;
            char file[]={"wordCount.c"};
            int ch;
            fp=fopen(file,"r");
            ch=getc(fp);
            while(ch!=EOF)
            {
                        putchar(ch);
                        ch=getc(fp);
            }
            fclose(fp);
return 0;
         
}
Output:

File Handling using C
Writing Text to a File
The fputc( ) function is similar to the putch( ) function, in the sense that both output characters. However, putch( ) function always writes to the VDU, whereas, fputc( ) writes to the file. Which file? The file signified by ft. The writing process continues till all characters from the source file have been written to the target file, following which the while loop terminates.
To write to a file, the file must be opened for writing e.g.
fp = fopen( file, “w” );
If the file does not exist already, it will be created. If the file does exist, it will be overwritten! So, be careful when opening files for writing, in case you destroy a file unintentionally. Opening files for writing can also fail. If you try to create a file in another users directory where you do not have access you will not be allowed and fopen will fail.
Character Output to Files
The function putc( c, fp ) writes a character to the file associated with the file pointer fp.
Example:
#include<stdio.h>

int main()
{
            FILE *fp;
            char file[]={"simple.txt"};
            char data[]={"This is a Simple Text File.\n\t1. This is Line No. 1.\n\t2. This is Line No. 2.\n"};
            fp=fopen(file,"w");
            if(fp==NULL)
            {
                        printf("\nUnable to Create the File %s",file);  

            }
            else
            {
                        fputs(data,fp);
                        printf("\n\t File \"%s\" created sucessfully\n",file);
            }
return 0;

}
Output:

File Handling using C
Working with Binary File functions
binary file is no different to a text file. It is a collection of bytes. In C Programming Language a byte and a character are equivalent. Hence a binary file is also referred to as a character stream, but there are two essential differences.
1.  No special processing of the data occurs and each byte of data is transferred to or from the disk unprocessed.
2.  C Programming Language places no constructs on the file, and it may be read from, or written to, in any manner chosen by the programmer.
Binary files can be either processed sequentially or, depending on the needs of the application, they can be processed using random access techniques. In C Programming Language, processing a file using random access techniques involves moving the current file position to an appropriate place in the file before reading or writing data. This indicates a second characteristic of binary files – they a generally processed using read and write operations simultaneously.
For example, a database file will be created and processed as a binary file. A record update operation will involve locating the appropriate record, reading the record into memory, modifying it in some way, and finally writing the record back to disk at its appropriate location in the file. These kinds of operations are common to many binary files, but are rarely found in applications that process text files.
The C file system includes two important functions: fread() and fwrite(). These functions can read and write any type of data, using any kind of representation.
Their prototypes are:
size_t fread(void *buffer, size_t size, size_t num,FILE *fp);

size_t fwrite(void *buffer, size_t size, size_t num, FILE *fp);
The fread() function reads from the file associated with fp, num number of objects, each object size bytes long, into buffer pointed to by buffer. It returns the number of objects actually read. If this value is 0, no objects have been read, and either end of file has been encountered or an error has occurred. You can use feof() or ferror() to find out which. Their prototypes are:
int feof(FILE *fp);
int ferror(FILE *fp);
The feof() function returns non-0 if the file associated with fp has reached the end of file, otherwise it returns 0. This function works for both binary files and text files. The ferror() function returns non-0 if the file associated with fp has experienced an error, otherwise itreturns 0.
The fwrite() function is the opposite of fread(). It writes to file associated with fpnumnumber of objects, each object size bytes long, from the buffer pointed to by buffer. It returns the number of objects written. This value will be less than num only if an output error as occurred.
The void pointer is a pointer that can point to any type of data without the use of a TYPE cast (known as a generic pointer). The type size_t is a variable that is able to hold a value equal to the size of the largest object surported by the compiler.

File Handling using C
Formatted Input/Output
So far we have dealt with reading and writing only characters and strings. There exist no standard library functions to read or write numbers under the category of high level, unformatted, text I/O functions.
The printf functions provide formatted output conversion.
int fprintf(FILE *stream, const char *format, ...)
fprintf converts and writes output to stream under the control of format. The return value is the number of characters written, or negative if an error occurred.
The format string contains two types of objects: ordinary characters, which are copied to the output stream, and conversion specifications, each of which causes conversion and printing of the next successive argument to fprintf. Each conversion specification begins with the character % and ends with a conversion character. Between the % and the conversion character there may be, in order:
·  Flags (in any order), which modify the specification:
o -, which specifies left adjustment of the converted argument in its field.
o +, which specifies that the number will always be printed with a sign.
o space: if the first character is not a sign, a space will be prefixed.
o 0: for numeric conversions, specifies padding to the field width with leading
zeros.
o #, which specifies an alternate output form. For o, the first digit will become
zero. For x or X, 0x or 0X will be prefixed to a non-zero result. For e, E, f, g,
and G, the output will always have a decimal point; for g and G, trailing zeros
will not be removed.
·  A number specifying a minimum field width. The converted argument will be printed in a field at least this wide, and wider if necessary. If the converted argument has fewer characters than the field width it will be padded on the left (or right, if left adjustment has been requested) to make up the field width. The padding character is normally space, but is 0 if the zero padding flag is present.  A period, which separates the field width from the precision.
·  A number, the precision, that specifies the maximum number of characters to be printed from a string, or the number of digits to be printed after the decimal point for e, E, or f conversions, or the number of significant digits for g or G conversion, or the number of digits to be printed for an integer (leading 0s will be added to make up the necessary width).
·  A length modifier hl (letter ell), or L. ``h'' indicates that the corresponding argument is to be printed as a short or unsigned short; ``l'' indicates that the argument is a long or unsigned long, ``L'' indicates that the argument is a long double.
Width or precision or both may be specified as *, in which case the value is computed by converting the next argument(s), which must be int.
The conversion characters and their meanings are shown in Table B.1. If the character after the % is not a conversion character, the behavior is undefined.
Formatted Input
The scanf function deals with formatted input conversion.
int fscanf(FILE *stream, const char *format, ...)
fscanf reads from stream under control of format, and assigns converted values through subsequent arguments, each of which must be a pointer. It returns when format is exhausted.
fscanf returns EOF if end of file or an error occurs before any conversion; otherwise it returns the number of input items converted and assigned.
The format string usually contains conversion specifications, which are used to direct
interpretation of input.

File Handling using C
Low Level Disk I/O
In low level disk I/O, data cannot be written as individual characters, or as strings or as formatted data. There is only one way data can be written or read in low level disk I/O functions—as a buffer full of bytes.
Writing a buffer full of data resembles the fwrite( ) function. However, unlike fwrite( ), the programmer must set up the buffer for the data, place the appropriate values in it before writing, and take them out after writing. Thus, the buffer in the low level I/O functions is very much a part of the program, rather than being invisible as in high level disk I/O functions.
Low level disk I/O functions offer following advantages:
Ø Since these functions parallel the methods that the OS uses to write to the disk, they are more efficient than the high level disk I/O functions.
Ø Since there are fewer layers of routines to go through, low level I/O functions operate faster than their high level counterparts.
Let us now write a program that uses low level disk input/output functions.
A Low Level File-copy Program
Earlier we had written a program to copy the contents of one file to another. In that program we had read the file character by character using fgetc( ). Each character that was read was written into the target file using fputc( ). Instead of performing the I/O on a character by character basis we can read a chunk of bytes from the source file and then write this chunk into the target file. While doing so the chunk would be read into the buffer and would be written to the file from the buffer. While doing so we would manage the buffer ourselves, rather than relying on the library functions to do so. This is what is low-level about this program. Here is a program which shows how this can be done.
/* File-copy program which copies text, .com and .exe etc  */
#include "fcntl.h"
#include "types.h"
#include "stat.h”

main ( int argc, char *argv[ ] )
{
char buffer[ 1024 ], source [ 256 ], target [ 256 ] ;

int ifilehandle, outhandle, bytes ;

printf ( "\nEnter source file name" ) ;
gets ( source ) ;

ifilehandle = open ( source, O_RDONLY | O_BINARY ) ;

if ( ifilehandle == -1 )
{
puts ( "Cannot open file" ) ;
exit( ) ;
}
printf ( "\nEnter target file name" ) ;
gets ( target ) ;
outhandle = open ( target, O_CREAT | O_BINARY | O_WRONLY, S_IWRITE ) ;
if ( ifilehandle == -1 )
{
puts ( "Cannot open file" ) ;
close ( ifilehandle ) ;
exit( ) ;
}
while ( 1 )
{
bytes = read ( ifilehandle, buffer, 1024 ) ;
if ( bytes > 0 )
write ( outhandle, buffer, bytes ) ;
else
break ;
}
close ( ifilehandle ) ;
close ( outhandle ) ;
}
Declaring the Buffer
The first difference that you will notice in this program is that we declare a character buffer,
char buffer[1024] ;
This is the buffer in which the data read from the disk will be placed. The size of this buffer is important for efficient operation. Depending on the operating system, buffers of certain sizes are handled more efficiently than others.
Opening a File
We have opened two files in our program, one is the source file from which we read the information, and the other is the target file into which we write the information read from the source file.
As in high level disk I/O, the file must be opened before we can access it. This is done using the statement,
ifilehandle = open ( source, O_RDONLY | O_BINARY ) ;
We open the file for the same reason as we did earlier—to establish communication with operating system about the file. As usual, we have to supply to open( ), the filename and the mode in which we want to open the file. The possible file opening modes are given below:
O_APPEND- Opens a file for appending
O_CREAT- Creates a new file for writing (has no effect if file already exists)
O_RDONLY- Creates a new file for reading only
O_RDWR- Creates a file for both reading and writing
O_WRONLY- Creates a file for writing only
O_BINARY- Creates a file in binary mode
O_TEXT- Creates a file in text mode
To use these permissions, both the files “types.h” and “stat.h” must be #included in the program along with “fcntl.h”.
File Handles
Instead of returning a FILE pointer as fopen( ) did, in low level disk I/O, open( ) returns an integer value called ‘file handle’. This is a number assigned to a particular file, which is used thereafter to refer to the file. If open( ) returns a value of -1, it means that the file couldn’t be successfully opened.
Interaction between Buffer and File
The following statement reads the file or as much of it as will fit into the buffer:
bytes = read ( ifilehandle, buffer, 1024 ) ;
The read( ) function takes three arguments. The first argument is the file handle, the second is the address of the buffer and the third is the maximum number of bytes we want to read.
The read( ) function returns the number of bytes actually read. This is an important number, since it may very well be less than the buffer size (1024 bytes), and we will need to know just how full the buffer is before we can do anything with its contents. In our program we have assigned this number to the variable bytes.
For copying the file, we must use both the read( ) and the write( ) functions in a while loop. The read( ) function returns the number of bytes actually read. This is assigned to the variable bytes. This value will be equal to the buffer size (1024 bytes) until the end of file, when the buffer will only be partially full. The variable bytes therefore is used to tell write( ), as to how many bytes to write from the buffer to the target file.

Graphics Programming with Turbo C
Introduction
Graphics programming in C Language is discussed rarely. We will discuss some important functions of graphics.h in C Language, at the end we will make a simple program to demonstrate the use of graphics functions. So let's start with the description of important functions and their use.
Graphics Drivers
Graphics drivers are a subset of device drivers and are applicable only in the graphics mode. They work in the above fashion to execute whatever task we have assigned them. Turbo C offers certain graphics drivers. These are the files with a BGI extension. Depending on what adapter is used, one of these drivers gets selected. Our programs have been developed on the VGA adapter. Thus we need the EGAVGA.BGI file as our graphics driver. In our example program given at the end of this chapter, gd has been assigned the valueDETECT, thereby asking initgraph( ) to figure out which BGI file is needed. This file is then loaded into memory. If we do not initiate gd with DETECT then it is our responsibility to set up gd and gm with appropriate values. Since most of the times we don’t want to be bothered with this responsibility we use the DETECT macro.
In a C Program first of all you need to initialize the graphics drivers on the computer. This is done using the initgraph method provided in graphics.h library. In the next few pages we will discuss graphics.h library in details. Important functions in graphic.h library will be discussed in details and samples programmes will be provided to show the power of C programming language.
Graphics mode Initialization
First of all we have to call the initgraph function that will intialize the graphics mode on the computer. initigraph have the following prototype.
void initgraph(int far *graphdriver, int far *graphmode, char far *pathtodriver);
Initgraph initializes the graphics system by loading a graphics driver from disk (or validating a registered driver) then putting the system into graphics mode.Initgraph also resets all graphics settings (color, palette, current position, viewport, etc.) to their defaults, then resets graphresult to 0.
*graphdriver
Integer that specifies the graphics driver to be used. You can give graphdriver a value using a constant of the graphics_drivers enumeration type.
*graphmode
Integer that specifies the initial graphics mode (unless *graphdriver = DETECT). If *graphdriver = DETECT, initgraph sets *graphmode to the highest resolution available for the detected driver. You can give *graphmode a value using a constant of thegraphics_modes enumeration type.
*pathtodriver
Specifies the directory path where initgraph looks for graphics drivers (*.BGI) first.
  1. If they're not there, initgraph looks in the current directory.
  2. If pathtodriver is null, the driver files must be in the current directory.
*graphdriver and *graphmode must be set to valid graphics_drivers and graphics_mode values or you'll get unpredictable results. (The exception is graphdriver = DETECT.)
After a call to initgraph, *graphdriver is set to the current graphics driver, and *graphmodeis set to the current graphics mode. You can tell initgraph to use a particular graphics driver and mode, or to autodetect the attached video adapter at run time and pick the corresponding driver. If you tell initgraph to autodetect, it calls detectgraph to select a graphics driver and mode.
Normally, initgraph loads a graphics driver by allocating memory for the driver (through_graphgetmem), then loading the appropriate .BGI file from disk.As an alternative to this dynamic loading scheme, you can link a graphics driver file (or several of them) directly into your executable program file.
Here is a sample program that initializes the graphics mode in C Language.
/* Sample program to draw a circle*/
#include<graphics.h>
#include<conio.h>
main()
{
  int gd=DETECT,gm;
  initgraph(&gd,&gm,""); /* initialization of graphic mode */
  circle(150,150,100);
  getch();
  closegraph(); /* Restore orignal screen mode */
}
/* End of program */
The graphics programming in c language is discussed in brief to provide an over view to the beginner.
Normally the screen which you view in DOS is in the text mode which means it is meant for text. And for graphics you need to initialize graphics mode. And for this to happen you need to include ?graphics.h?.
circle(x coordinate ,y coordinate , radius);
The circle command takes a X coordinate which means Vertical axis and Y coordinatewhich means Horizontal axis. And the last one is the radius of the circle. closegraph();
With out this function the screen mode will still remain in graphic mode and when you come out, to DOS you will see a different screen, which is not in the text mode.
/*A program to draw a space with stars*/
#include<graphics.h>

main()

{

  int gd=DETECT,gm;

  int i,x,y;

  initgraph(&gd,&gm,"");

  line(0,0,640,0);

  line(0,0,0,480);

  line(639,0,639,480);

  line(639,479,0,479);

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

  {

    x=rand()%639;

    y=rand()%480;

    putpixel(x,y,15);

  }

  getch();

  closegraph();

}

/* End of program */

Graphics Programming with Turbo C
Getting started with Graphics mode
Graphics.h
Below are the important functions and their description mostly used in graphics applications in C Language.
Function initgraph
This function is used to load the graphics drivers and initialize the graphics system. For every function, that uses graphics mode, graphics mode must be initialized before using that function.
void far initgraph(int far *driver, int far *mode, char far *path)
Path determines that path to the specified graphics driver.
Function detectgraph
Detectgraph function determines the graphics hardware in the system, if the function finds a graphics adapter then it returns the highest graphics mode that the adapter supports.
void far detectgraph(int far *driver, int far *mode)
Function cleardevice
This function clears the graphics screen contents and return the control to the location (0,0)
void far cleardevice(void)
Function closegraph
This function shutdown the graphics mode and returns to the position it was before theinitgraph function was called. Closegraph function releases all the resources occupied by the graphics system like memryfontsdrivers etc...
void far closegraph(void)
Function arc
This function draws an arc from start to the end point. It uses the radius and the angle inputted in the function parameter. Function prototye is
void far arc (int x, int y, int start, int end, int radius)
Function bar
The bar() functions draws a rectangular bar on the screen. It takes four parameters of type int which are infact the points on the graphics screen, and fills the bar with the defined fill-pattern. Function prototye is
void far bar(int left, int top, int right, int bottom)
Here left and top are the starting point for the rectangular bar from x and y coordinates respectively and right and bottom are the ending point.
Function bar3d
As the name suggests that this function will draw the 3 Dimentional rectangular bar on the screen. Bar3d function takes six parameters of which four are the points , fifth one is the depth of the bar and sixth is the flag to indicate the 3D view. Here is the prototype of the bar3d function.
void far bar3d(int left, int top, int right, int bottom, int depth, int topflag)
Function circle
Draws the circle on the screen using a point(x,y) and the radius for the circle.
void far circle(int x, int y, int radius)
Function drawpoly
This function draws an outline of a polygon.
void far drawpoly(int numpoints, int far *points)
Here numpoints is the number of end points in the polygon. And points is the integer array which contains the x and y coordinates of the points.
Function ellipse
Draws an ellipse using the current drawing color.
void far ellipse(int x, int y, int start, int end, int xradius, int yradius)
Function floodfill
This function fills an object drawn on the graphics screen with the defined color and fill pattern. Now if the x,y coordinates lie within the boundries of the object then it will fill the interior of the object otherwise out side the object.
void far floodfill(int x, int y, int border)
Function line
This function draws a line in the graphics mode.
void far line(int startx, int starty, int endx, int endy)
Function outtext
Displays a text string on the grpahics screen.
void far outtext(char far *str)
Function outtextxy
Displays the text at a specified position in graphics mode.
void far outtext(int x, int y, char *str)
Function putpixel
Prints a pixel at the specified point on the screen.
void far putpixel(int x, int y, int color)
Function rectangle
Draws a rectangular box on the screen using the points given in the parameters.
void far rectangle(int left, int top, int right, int bottom)
A small C Language Program that uses the Graphics Functions
#include <stdio.h>

#include <graphics.h>

#include <conio.h>

#include <process.h>


void main(void)

{

               int mx, my;

               /* request auto detection */

               int gd= DETECT, gm, errorcode;

               initgraph(&gd,&gm,"F:\\tc\\bgi");


               /* read result of initialization */

               errorcode = graphresult();


               if (errorcode != grOk)  /* an error occurred */

               {

                               printf("Graphics error: %s\n", grapherrormsg(errorcode));

                               printf("Press any key to halt:");

                               getch();

                               exit(1);

             /* return with error code */

               }

               mx = (getmaxx() / 2);

               my = (getmaxy() / 2);


               //SET baqckground color

               setfillstyle(9, 1);

               bar(0,0,getmaxx(),getmaxy());


               //DRAW a bar, and make it look like a 3d bar

               setfillstyle(1,7);

               //bar(50,20,600,400);


               //DRAW lines for the top and left side

               setcolor(15);                line(50,20,600,20);

               line(51,21,599,21);

               line(50,20,50,400);

               line(51,21,51,399);


               //DRAW lines for the bottom and right side

               setcolor(8);

               line(600,20,600,400);

               line(599,21,599,400);

               line(50,400,600,400);

               line(51,399,600,399);


               //DRAW two 3D bars for the left and right side

               setfillstyle(9,8);

               bar(70,40,100,380);

               bar(70,40,550,70);

               bar(70,350,550,379);

               bar(545,40,575,380);


               //PRINT 3D text CALENDAR 2002

               settextstyle(1, 0, 4);

               settextjustify(1,1);

               setcolor(LIGHTGREEN);

               outtextxy(mx+2, my - 46, "Thank You!");

               setcolor(LIGHTGREEN);

               outtextxy(mx + 1, my - 45, "Thank You!");

               setcolor(GREEN);

               outtextxy(mx + 2, my - 44, "Thank You!");


               //PRINT 3D text 2002

               setcolor(LIGHTGREEN);

               outtextxy(mx, my + 10, "2006");

               setcolor(LIGHTGREEN);

               outtextxy(mx + 1, my + 11, "2006");

               setcolor(GREEN);

               outtextxy(mx + 2, my + 12, "2006");


               //PRINT copyright notice

               settextstyle(2, 0, 5);

               setcolor(WHITE);

               outtextxy(mx + 1, my + 150, "Copyright http://www.mycplus.com/");


               //Print the circle around the text

               //the text is "Thank You!"

               setcolor(GREEN);

               circle(mx,my-30,120);


               //Print the ellipse around the text

               //the text is "Thank You!"

               setcolor(GREEN);

               ellipse(mx,my-30,0,360,180,70);


               //Print the 3D line below the text

               //the text is "Thank You!"

               setcolor(CYAN);

               line(230,220,410,220);

               bar3d(235,225,415,225,4,1);


               getch(); //PAUSE for a while

               closegraph();

}

Graphics Programming with Turbo C
Working with Shapes
Turbo C has a good collection of graphics libraries. If you know the basics of C, you can easily learn graphics programming.
To start programming, let us write a small program that displays a circle on the screen.
/*  simple.c
    example 1.0
*/
#include<graphics.h>
#include<conio.h>

void main()
{
    int gd=DETECT, gm;

    initgraph(&gd, &gm, "c:\\turboc3\\bgi " );
    circle(200,100,150);

    getch();
    closegraph();
}
To run this program, you need graphics.h header filegraphics.lib library file and Graphics driver (BGI file) in the program folder. These files are part of Turbo C package. In all our programs we used 640x480 VGA monitor. So all the programs are according to that specification. You need to make necessary changes to your programs according to your screen resolution. Graphics driver used for VGA monitor is EGAVGA.BGI.
Here, initgraph() function initializes the graphics mode and clears the screen. We will study the difference between text mode and graphics mode in detail latter.
InitGraph:
Initializes the graphics system.
Declaration:
void far initgraph(int far *graphdriver, int far *graphmode, char far *pathtodriver);
Remarks: To start the graphics system, you must first call initgraph.
initgraph initializes the graphics system by loading a graphics driver from disk (or validating a registered driver) then putting the system into graphics mode.
initgraph also resets all graphics settings (color, palette, current position, viewport, etc.) to their defaults, then resets graphresult to 0.
Arguments:
*graphdriver: Integer that specifies the graphics driver to be used. You can give graphdriver a value using a constant of the graphics drivers enumeration type.
*graphmode: Integer that specifies the initial graphics mode (unless *graphdriver = DETECT). If *graphdriver = DETECT, initgraph sets
*graphmode to the highest resolution available for the detected driver. You can give *graphmode a value using a constant of the graphics_modes enumeration type.
pathtodriver: Specifies the directory path where initgraph looks for graphics drivers (*.BGI)first. If they're not there, initgraph looks in the current directory. If pathtodriver is null, the driver files must be in the current directory. This is also the path settextstyle searches for the stroked character font files (*.CHR).
closegraph() function switches back the screen from graphcs mode to text mode. It clears the screen also. A graphics program should have a closegraph function at the end of graphics. Otherwise DOS screen will not go to text mode after running the program. Here,closegraph() is called after getch() since screen should not clear until user hits a key.
If you have the BGI file in the same folder of your program, you can just leave it as "" only. you need not mention *graphmode if you give *graphdriver as DETECT.
In graphics mode, all the screen co-ordinates are mentioned in terms of pixels. Number of pixels in the screen decides resolution of the screen. In the example 1.0, circle is drawn with x-coordinate of the center 200y-coordinate 100 and radius 150 pixels. All the coordinates are mentioned with respect to top-left corner of the screen.
Basic Shapes and Colors:
Now let us write a program to draw some basic shapes.
#include<graphics.h>
#include<conio.h>

void main()
{
    int gd=DETECT, gm;
    int poly[12]={350,450, 350,410, 430,400, 350,350, 300,430, 350,450 };
    initgraph(&gd, &gm, "");
    
    circle(100,100,50);
    outtextxy(75,170, "Circle");
    rectangle(200,50,350,150);
    outtextxy(240, 170, "Rectangle");
    ellipse(500, 100,0,360, 100,50);
    outtextxy(480, 170, "Ellipse");
    line(100,250,540,250);
    outtextxy(300,260,"Line");

    sector(150, 400, 30, 300, 100,50);
    outtextxy(120, 460, "Sector");
    drawpoly(6, poly);
    outtextxy(340, 460, "Polygon");
    getch();
    closegraph();
}
Here is the screenshot of output:
Here, circle() function takes x, y coordinates of the circle with respect to left top of the screen and radius of the circle in terms of pixels as arguments. Not that, in graphics, almost all the screen parameters are measured in terms of pixels.
Function outtextxy() displays a string in graphical mode. You can use different fonts, text sizes, alignments, colors and directions of the text that we will study later. Parameters passed are x and y coordinates of the position on the screen where text is to be displayed. There is another function outtext() that displayes a text in the current position. Current position is the place where last drawing is ended. These functions are declared as follows:
void far outtextxy(int x, int y, char *text);
void far outtext(char *text);
Circle, arc, pieslice are declared as follows:
Declaration:
  •  void far arc(int x, int y, int stangle, int endangle, int radius);
  •  void far circle(int x, int y, int radius);
  •  void far pieslice(int x, int y, int stangle, int endangle, int radius);
Remarks:
  • arc draws a circular arc in the current drawing color.
  • circle draws a circle in the current drawing color.
  • pieslice draws a pie slice in the current drawing color, then fills it using
    the current fill pattern and fill color.
Arguments:
  • (x,y): Center point of arc, circlew, or pie slice
  • stangle: Start angle in degrees
  • endangle: End angle in degrees
  • radius: Radius of arc, circle, and pieslice
Here, stangle and endangle are in degrees starting from the +ve x-axis in the polar coordinate system in the anti-clockwise direction. if stangle is 0, endangle is 360, it will draw a full circle. Refer this figure for clear idea: For the details of current color, fill color and fill patterns, refer the sections Lines and Colors.
Another basic shape that we come across is a rectangle. To draw a border, use rectangle with the coordinates of outline, to draw a square use rectangle with same height and width.drawpoly() and fillpoly() are two functions useful to draw any polygons. To use these functions, store coordinates of the shape in an array and pass the address of array as an argument to the function. By looking at the output of the previous program, you can understand what drawpoly is. fillpoly is similar except that it fills in the shape with current fill color.
Declaration:
  • void far rectangle(int left, int top, int right, int bottom);
  • void far drawpoly(int numpoints, int far *polypoints);
  • void far fillpoly(int numpoints, int far *polypoints);
Remarks:
  • rectangle draws a rectangle in the current line style, thickness, and drawing color.
  • drawpoly draws a polygon using the current line style and color.
  • fillpoly draws the outline of a polygon using the current line style and color, then fills the polygon using the current fill pattern and fill color.
Arguments:
  • (left,top) is the upper left corner of the rectangle, and (right,bottom) is its lower right corner.
  • numpoints:  Specifies number of points
  • *polypoints: Points to a sequence of (numpoints x 2) integers. Each pair of integers gives the x and y coordinates of a point on the polygon.
To draw a closed polygon with N points, numpoints should be N+1 and the array polypoints[] should contain 2(N+1) integers with first 2 integers equal to last 2 integers.
Let us study more about shapes latter. Here is some idea about colors. There are 16 colors declared in graphics.h as listed bellow.
BLACK:0
BLUE:1
GREEN:2
CYAN:3
RED:4
MAGENTA:5
BROWN:6
LIGHTGRAY:7
DARKGRAY:8
LIGHTBLUE:9
LIGHTGREEN:10
LIGHTCYAN:11
LIGHTRED:12
LIGHTMAGENTA:13
YELLOW:14
WHITE:15
To use these colors, use functions setcolor()setbkcolor() and setfillstyle()setcolor()function sets the current drawing color. If we use setcolor(RED); and draw any shape, line or text after that, the drawing will be in red color. You can either use color as defined above or number like setcolor(4);setbkcolor() sets background color for drawing. Setfillstyle sets fill pattern and fill colors. After calling setfillstyle, if we use functions like floodfillfillpoly,bar etc, shpes will be filled with fill color and pattern set using setfillstyle. These function declarations are as follows.
Declaration:
  •  void far setfillstyle(int pattern, int color);
  • void far setcolor(int color);
  • void far setbkcolor(int color);
Remarks:
  • setfillstyle sets the current fill pattern and fill color.
  • setcolor sets the current drawing color to color, which can range from 0 to getmaxcolor.
  • setbkcolor sets the background to the color specified by color.
The parameter pattern in setfillstyle is as follows:
 NamesValueMeans  Fill With...
EMPTY_FILL0Background color
SOLID_FILL1Solid fill
LINE_FILL2---
LTSLASH_FILL3///
SLASH_FILL4///, thick lines
BKSLASH_FILL5\\\, thick lines
LTBKSLASH_FILL6 \\\
HATCH_FILL7Light hatch
XHATCH_FILL8Heavy crosshatch
INTERLEAVE_FILL9Interleaving lines
WIDE_DOT_FILL10Widely spaced dots
CLOSE_DOT_FILL11Closely spaced dots
USER_FILL12User-defined fill pattern
Here is an example program with colorspixelsbarcleardevice etc. stdlib.h is used for random number generation. We have a function random(no), it returns a random number between 0 an no. The effect is by drawing random radius, random color circles with same center and random pixels. kbhit() function(defined in conio.h) returns a nonzero value when a key is pressed in the keyboard. So, the loop will continue until a key is pressed.
#include "graphics.h"
#include "conio.h"
#include "stdlib.h"

void main()
{
    int gd,gm;
    gd=DETECT;

    initgraph(&gd, &gm, "");
    setcolor(3);
    setfillstyle(SOLID_FILL,RED);
    bar(50, 50, 590, 430);
  
    setfillstyle(1, 14);
    bar(100, 100, 540, 380);

    while(!kbhit())
    {
        putpixel(random(439)+101,  random(279)+101,random(16));
        setcolor(random(16));
        circle(320,240,random(100));
    }
    getch();
    closegraph();
}

0 comments: