Category: 17. Miscellaneous Topics

https://cdn3d.iconscout.com/3d/premium/thumb/atom-3d-icon-png-download-5220568.png

  • Command Line Arguments in C

    In any C program, there may be multiple functions, but the main() function remains the entry point from where the execution starts. While the other functions may have one or more arguments and a return type, the main() function is generally written with no arguments. The main() function also has a return value of “0”.

    intmain(){......return0;}

    Inside the main() function, there may be scanf() statements to let the user input certain values, which are then utilized.

    #include <stdio.h>intmain(){int a;scanf("%d",&a);printf("%d", a);return0;}

    What are Command Line Arguments?

    Instead of invoking the input statement from inside the program, it is possible to pass data from the command line to the main() function when the program is executed. These values are called command line arguments.

    Command line arguments are important for your program, especially when you want to control your program from outside, instead of hard coding those values inside the code.

    Let us suppose you want to write a C program “hello.c” that prints a “hello” message for a user. Instead of reading the name from inside the program with scanf(), we wish to pass the name from the command line as follows −

    C:\users\user>hello Prakash
    

    The string will be used as an argument to the main() function and then the “Hello Prakash” message should be displayed.

    argc and argv

    To facilitate the main() function to accept arguments from the command line, you should define two arguments in the main() function argc and argv[].

    argc refers to the number of arguments passed and argv[] is a pointer array that points to each argument passed to the program.

    intmain(int argc,char*argv[]){......return0;}

    The argc argument should always be non-negative. The argv argument is an array of character pointers to all the arguments, argv[0] being the name of the program. After that till “argv [argc – 1]“, every element is a command-line argument.

    Open any text editor and save the following code as “hello.c” −

    #include <stdio.h>intmain(int argc,char* argv[]){printf("Hello %s", argv[1]);return0;}

    The program is expected to fetch the name from argv[1] and use it in the printf() statement.

    Instead of running the program from the Run menu of any IDE (such as VS code or CodeBlocks), compile it from the command line −

    C:\Users\user>gcc -c hello.c -o hello.o
    

    Build the executable −

    C:\Users\user>gcc -o hello.exe hello.o
    

    Pass the name as a command line argument −

    C:\Users\user>hello Prakash
    Hello Prakash
    

    If working on Linux, the compilation by default generates the object file as “a.out“. We need to make it executable before running it by prefixing “./” to it.

    $ chmod a+x a.o
    $ ./a.o Prakash
    

    Example

    Given below is a simple example that checks if there is any argument supplied from the command line and takes action accordingly −

    #include <stdio.h>intmain(int argc,char*argv[]){if(argc ==2){printf("The argument supplied is %s\n", argv[1]);}elseif(argc >2){printf("Too many arguments supplied.\n");}else{printf("One argument expected.\n");}}
    Output

    When the above code is compiled and executed with a single argument, it produces the following output −

    $./a.out testing
    The argument supplied is testing.
    

    When the above code is compiled and executed with two arguments, it produces the following output −

    $./a.out testing1 testing2
    Too many arguments supplied.
    

    When the above code is compiled and executed without passing any argument, it produces the following output −

    $./a.out
    One argument expected
    

    It should be noted that argv[0] holds the name of the program itself and argv[1] is a pointer to the first command line argument supplied, and *argv[n] is the last argument. If no arguments are supplied, then argc will be set at “1” and if you pass one argument, then argc is set at “2“.

    Passing Numeric Arguments from the Command Line

    Let us write a C program that reads two command line arguments, and performs the addition of argv[1] and argv[2].

    Example

    Start by saving the code below −

    #include <stdio.h>intmain(int argc,char* argv[]){int c = argv[1]+ argv[2];printf("addition: %d", c);return0;}

    Output

    When we try to compile, you get the error message −

    error: invalid operands to binary + (have 'char *' and 'char *')
     int c = argv[1]+argv[2];
    
         ~~~~~~~~~~~~~~

    This is because the “+” operator cannot have non-numeric operands.

    The atoi() Function

    To solve this issue, we need to use the library function atoi() that converts the string representation of a number to an integer.

    Example

    The following example shows how you can use the atoi() function in a C program −

    #include <stdio.h>#include <stdlib.h>intmain(int argc,char* argv[]){int c =atoi(argv[1])+atoi(argv[2]);printf("addition: %d", c);return0;}
    Output

    Compile and build an executive from “add.c” and run from the command line, passing numeric arguments −

    C:\Users\user>add 10 20
    addition: 30
    

    Example

    You pass all the command line arguments separated by a space, but if the argument itself has a space, then you can pass such arguments by putting them inside double quotes (” “) or single quotes (‘ ‘).

    In this example, we will pass a command line argument enclosed inside double quotes −

    #include <stdio.h>intmain(int argc,char*argv[]){printf("Program name %s\n", argv[0]);if(argc ==2){printf("The argument supplied is %s\n", argv[1]);}elseif(argc >2){printf("Too many arguments supplied.\n");}else{printf("One argument expected.\n");}}
    Output

    When the above code is compiled and executed with a single argument separated by space but inside double quotes, it produces the following output −

    $./a.out "testing1 testing2"
    
    Program name ./a.out
    The argument supplied is testing1 testing2
    
  • Random Number Generation in C

    The stdlib.h library in C includes the rand() function that returns an integer randomly, between “0” and the constant RAND_MAX.

    The rand() function generates pseudo-random numbers. They are not truly random. The function works on Linear Congruential Generator (LCG) algorithm.

    intrand(void);

    Example 1

    The following code calls the rand() function thrice, each time it is likely to come with a different integer −

    #include <stdio.h>#include<stdlib.h>intmain(){printf("%ld\n",rand());printf("%ld\n",rand());printf("%ld\n",rand());return0;}

    Output

    Run the code and check its output −

    41
    18467
    6334
    

    The rand() function doesn’t have a built-in mechanism to set the seed. By default, it might use a system specific value (often based on the time the program starts).

    Note: The srand() function is used to improve the randomness by providing a seed to the rand() function.

    Example 2

    The following program returns a random number between 0 to 100. The random integer returned by the rand() function is used as a numerator and its mod value with 100 is calculated to arrive at a random number that is less than 100.

    #include <stdio.h>#include<stdlib.h>intmain(){for(int i =1; i <=5; i++){printf("random number %d: %d \n", i,rand()%100);}return0;}

    Output

    Run the code and check its output −

    random number 1: 41
    random number 2: 67
    random number 3: 34
    random number 4: 0
    random number 5: 69
    

    Example 3

    You can also obtain a random number between a given range. You need to find the mod value of the result of rand() divided by the range span, add the result to the lower value of the range.

    #include <stdio.h>#include<stdlib.h>intmain(){int i, num;int lower=50, upper=100;for(i =1; i <=5; i++){
    
      num =(rand()%(upper - lower +1))+ lower;printf("random number %d: %d \n", i,num);}return0;}</code></pre>

    Output

    Run the code and check its output −

    random number 1: 91
    random number 2: 55
    random number 3: 60
    random number 4: 81
    random number 5: 94
    

    The srand() Function

    The stdlib.h library also includes the srand() function that is used to seed the rand() functions random number generator.

    You would use the following syntax to use the srand() function −

    voidsrand(unsigned seed);

    OR

    intsrand(unsignedint seed);

    The seed parameter is an integer value to be used as seed by the pseudo-random number generator algorithm.

    Note: If srand() is not initialized, then the seed value in rand() function is set as srand(1).

    Usually, the srand() function is used with the value returned by time(NULL) (which represents the current time since the epoch) as a parameter to improve the randomness of the pseudo-random numbers generated by rand() in C.

    Since the time value changes all the time, this will have different seed values, leading to more varied random sequences. As a result, if you generate random number multiple times, then it will likely result in different random value every time.

    Example 1

    Take a look at the following example −

    #include <stdio.h>#include<stdlib.h>#include <time.h>intmain(){srand(time(NULL));printf("Random number: %d \n",rand());return0;}

    Output

    Every time a new random integer between 0 to RAND_MAX will be displayed.

    Random number: 1436786055 
    

    Example 2

    We can include srand() to generate a random number between a given range.

    #include <stdio.h>#include<stdlib.h>#include <time.h>intmain(){int i, num;time_t t;int lower =100, upper =200;srand((unsigned)time(&t));for(i =1; i <=5; i++){
    
      num =(rand()%(upper - lower +1))+ lower;printf("random number number %d: %d \n", i, num);}return0;}</code></pre>

    Output

    Run the code and check its output −

    random number number 1: 147
    random number number 2: 171
    random number number 3: 173
    random number number 4: 112
    random number number 5: 181
    

    The random number generation offered by rand() function is not truly random. With the same seed, you'll always get the same sequence. It also has a limited range as it generates random numbers within a specific range (0 to RAND_MAX).

    To improving the Randomness, you need to use a good seed value with high unpredictability like system time or a high-resolution timer. You can also use third party libraries for wider range random numbers.

  • Static Keyword

    What is static Keyword in C?

    The static keyword in C is one of the storage class specifiers which has different meanings based on the context in which it is used.

    The “static” keyword is used to declare a static variable as well as to define a static function. When declared as “static”, a variable represents a static storage class.

    static function is available only inside the program file (with “.c” extension) in which it is defined. One cannot use the “extern” keyword to import a static function into another file.

    Uses of static Keyword

    The following are the different uses of the static keyword

    • Static Local Variable: When a local variable is declared with the static keyword, its lifetime will be till the end of the program and it retains the value between the function calls.
    • Static Global Variable: When a global variable is declared with the static keyword, it can only be accessed within the same file. It is useful when you want to make a global variable as a private global variable to the file in which it is declared.
    • Static Functions: When you function is declared as a static function, its scope will be limited to the file in which the function is declared. You cannot access the function in other files.

    Static Variables (static Keyword with Variables)

    When a variable is declared as static, it is initialized only once. The compiler persists with the variable till the end of the program. A static variable is also used to store data that should be shared between multiple functions.

    Here are some of the important points to note regarding a static variable −

    • The compiler allocates space to the static variable in computers main memory.
    • Unlike auto, a static variable is initialized to zero and not garbage.
    • A static variable is not re-initialized on every function call, if it is declared inside a function.
    • A static variable has local scope.

    Example of static Keyword with Variables

    In the following example, the variable “x” in the counter() function is declared as static. It is initialized to “0” when the counter() function is called for the first time. On each subsequent call, it is not re-initialized; instead it retains the earlier value.

    #include <stdio.h>intcounter();intmain(){counter();counter();counter();return0;}intcounter(){staticint x;printf("Value of x as it enters the function: %d\n", x);
       x++;printf("Incremented value of x: %d\n", x);}

    Output

    When you run this code, it will produce the following output −

    Value of x as it enters the function: 0
    Incremented value of x: 1
    Value of x as it enters the function: 1
    Incremented value of x: 2
    Value of x as it enters the function: 2
    Incremented value of x: 3
    

    A static variable is similar to a global variable, as both of them, are initialized to 0 (for numeric types) or null pointers (for pointers) unless explicitly assigned. However, the scope of the static variable is restricted to the function or block in which it is declared.

    Static Functions (static Keyword with Functions)

    By default, every function is treated as global function by the compiler. They can be accessed anywhere inside a program.

    When prefixed with the keyword “static” in the definition, we get a static function that has a scope limited to its object file (the compiled version of a program saved with “.c” extension). This means that the static function is only visible in its object file.

    A static function can be declared by placing the keyword “static” before the function name.

    Example of static Keyword with Function (in Multiple Files)

    Open a console application with the CodeBlocks IDE. Add two files “file1.c” and “main.c”. The contents of these files are given as follows −

    Contents of “file1.c” −

    staticvoidstaticFunc(void){printf("Inside the static function staticFunc() ");}

    Contents of “main.c” −

    #include <stdio.h>#include <stdlib.h>intmain(){staticFunc();return0;}

    Now, if the above console application project is built, then we will get an error, i.e., “undefined reference to staticFunc()”. This happens as the function staticFunc() is a static function and it is only visible in its object file.

    Example of static Keyword with Function (in the Same File)

    The following program demonstrates how static functions work in a C program −

    #include <stdio.h>staticvoidstaticFunc(void){printf("Inside the static function staticFunc() ");}intmain(){staticFunc();return0;}

    Output

    The output of the above program is as follows −

    Inside the static function staticFunc()
    

    In the above program, the function staticFunc() is a static function that prints “Inside the static function staticFunc()”. The main() function calls staticFunc(). This program works correctly as the static function is called only from its own object file.

    Example of static Keyword with Multiple Functions

    You can have multiple static functions in the same object file, as illustrated in the following example −

    #include <stdio.h>#include <stdlib.h>#include <math.h>// define the static functionstaticintsquare(int num){return num * num;}staticvoidvoidfn(){printf("From inside the static function.\n");}staticintintfn(int num2){returnsqrt(num2);}intmain(){int n1, val;
       n1 =16;
       val =square(n1);// Call voidfn static functionprintf("The square of the %d : %d\n", n1, val);voidfn();// Call intfn static function
       val =intfn(n1);printf("The square root of the %d : %d\n", n1, val);return0;}

    Output

    When you run this code, it will produce the following output −

    The square of the 16: 256
    From inside the static function.
    The square root of the 16: 4
    
  • Math Functions

    C Math Functions

    C language provides various functions to perform mathematical operations on numbers such as finding trigonometric ratios, calculating log and exponentials, rounding the numbers, etc.. To use these math functions in a C program, you need to include math.h header file.

    We have categorized math functions into the following categories −

    • Trigonometric Functions
    • Inverse Trigonometric Functions
    • Hyperbolic Functions
    • Exponentiation and Logarithmic Functions
    • Floating-Point Functions
    • Power and Square Root Functions
    • Rounding Functions
    • Modulus Functions

    Trigonometric Functions

    The math.h library defines the function sin()cos(), and tan() that return the respective trigonometric ratios, sine, cosine and tangent of an angle.

    These functions return the respective ratio for a given double type representing the angle expressed in radians. All the functions return a double value.

    doublesin(double x)doublecos(double x)doubletan(double x)

    For all the above functions, the argument “x” is the angle in radians.

    Example

    The following example shows how you can use trigonometric functions in C −

    #include <stdio.h>#include <math.h>#define PI 3.14159265intmain(){double x, sn, cs, tn, val;
    
       x =45.0;
       val = PI /180;
    
       sn =sin(x*val);
       cs =cos(x*val);
       tn =tan(x*val);printf("sin(%f) : %f\n", x, sn);printf("cos(%f) : %f\n", x, cs);printf("tan(%f) : %f\n", x, tn);return(0);}

    Output

    When you run this code, it will produce the following output −

    sin(45.000000) : 0.707107
    cos(45.000000) : 0.707107
    tan(45.000000) : 1.000000
    

    Inverse Trigonometric Functions

    The math.h library also includes inverse trigonometric functions, also known as arcus functions or anti-trigonometric functions. They are the inverse functions of basic trigonometric functions. For example, asin(x) is equivalent to $&bsol;mathrm{sin^{-1}(x)}$. The other inverse functions are acos(), atan() and atan2().

    The following asin() function returns the arc sine of “x” in the interval [-pi/2, +pi/2] radians −

    doubleasin(double x)

    The following acos() function returns principal arc cosine of “x” in the interval [0, pi] radians −

    doubleacos(double x)

    The following atan() function returns the principal arc tangent of “x” in the interval [-pi/2, +pi/2] radians.

    doubleatan(double x)

    Example 1

    The following example demonstrates how you can use inverse trigonometric functions in a C program −

    #include <stdio.h>#include <math.h>#define PI 3.14159265intmain(){double x, asn, acs, atn, val;
    
       x =0.9;
       val =180/PI;
    
       asn =asin(x);
       acs =acos(x);
       atn =atan(x);printf("asin(%f) : %f in radians\n", x, asn);printf("acos(%f) : %f in radians\n", x, acs);printf("atan(%f) : %f in radians\n", x, atn);
    
       asn =(asn *180)/ PI;
       acs =(acs *180)/ PI;
       atn =(atn *180)/ PI;printf("asin(%f) : %f in degrees\n", x, asn);printf("acos(%f) : %f in degrees\n", x, acs);printf("atan(%f) : %f in degrees\n", x, atn);return(0);}

    Output

    When you run this code, it will produce the following output −

    asin(0.900000) : 1.119770 in radians
    acos(0.900000) : 0.451027 in radians
    atan(0.900000) : 0.732815 in radians
    asin(0.900000) : 64.158067 in degrees
    acos(0.900000) : 25.841933 in degrees
    atan(0.900000) : 41.987213 in degrees
    

    The atan2() function returns the arc tangent in radians of “y/x” based on the signs of both values to determine the correct quadrant.

    double atan2(double y, double x)

    This function returns the principal arc tangent of “y / x” in the interval [-pi, +pi] radians.

    Example 2

    Take a look at the following example −

    #include <stdio.h>#include <math.h>#define PI 3.14159265intmain(){double x, y, ret, val;
    
       x =-7.0;
       y =7.0;
       val =180.0/ PI;
    
       ret =atan2(y,x)* val;printf("The arc tangent of x = %lf, y = %lf ", x, y);printf("is %lf degrees\n", ret);return(0);}

    Output

    Run the code and check its output −

    The arc tangent of x = -7.000000, y = 7.000000 is 135.000000 degrees
    

    Hyperbolic Functions

    In Mathematics, hyperbolic functions are similar to trigonometric functions but are defined using the hyperbola rather than the circle. The math.h header file provides sinh(), cosh(), and tanh() functions.

    doublesinh(double x)

    This function returns hyperbolic sine of x.

    doublecosh(double x)

    This function returns hyperbolic cosine of x.

    doubletanh(double x)

    This function returns hyperbolic tangent of x.

    Example

    The following example shows how you can use hyperbolic functions in a C program −

    #include <stdio.h>#include <math.h>#define PI 3.14159265intmain(){double x,val, sh, ch, th;
    
       x =45;
       val = PI/180.0;
    
       sh =sinh(x*val);
       ch =cosh(x*val);
       th =tanh(x*val);printf("The sinh(%f) = %lf\n", x, sh);printf("The cosh(%f) = %lf\n", x, ch);printf("The tanh(%f) = %lf\n", x, th);return(0);}

    Output

    Run the code and check its output −

    The sinh(45.000000) = 0.868671
    The cosh(45.000000) = 1.324609
    The tanh(45.000000) = 0.655794
    

    Exponentiation and Logarithmic Functions

    The “math.h” library includes the following functions related to exponentiation and logarithms −

    exp() Function: It returns the value of e raised to the xth power. (Value of e – Eulers number is 2.718 approx)

    doubleexp(double x)

    log() Function: It returns the natural logarithm (base-e logarithm) of “x”.

    doublelog(double x)

    Note that Logarithmic functions are equivalent to the exponential functions inverse.

    log10() Function: It returns the common logarithm (base-10 logarithm) of “x”.

    doublelog10(double x)

    Example

    The following example shows how you can use exponentiation and logarithmic functions in a C program −

    #include <stdio.h>#include <math.h>#define PI 3.14159265intmain(){double x =2;double e, ln, ls;
       e =exp(2);
       ln =log(e);printf("exp(%f): %f log(%f): %f\n",x, e, e, ln);
    
       ln =log(x);printf("log(%f): %f\n",x,ln);
       ls =log10(x);printf("log10(%f): %f\n",x,ls);return(0);}

    Output

    When you run this code, it will produce the following output −

    exp(2.000000): 7.389056 log(7.389056): 2.000000
    log(2.000000): 0.693147
    log10(2.000000): 0.301030
    

    Floating-Point Functions

    The frexp() and ldexp() functions are used for floating-point manipulation.

    frexp() Function

    The “math.h” header file also includes the frexp() function. It breaks a floating-point number into its significand and exponent.

    doublefrexp(double x,int*exponent)

    Here, “x” is the floating point value to be computed and “exponent” is the pointer to an int object where the value of the exponent is to be stored.

    This function returns the normalized fraction.

    Example

    Take a look at the following example −

    #include <stdio.h>#include <math.h>intmain(){double x =1024, fraction;int e;
    
       fraction =frexp(x,&e);printf("x = %.2lf = %.2lf * 2^%d\n", x, fraction, e);return(0);}

    Output

    Run the code and check its output −

    x = 1024.00 = 0.50 * 2^11
    

    ldexp() Function

    The ldexp() function combines a significand and an exponent to form a floating-point number. Its syntax is as follows −

    doubleldexp(double x,int exponent)

    Here, “x” is the floating point value representing the significand and “exponent” is the value of the exponent. This function returns (x * 2 exp)

    Example

    The following example shows how you can use this ldexp() function in a C program −

    #include <stdio.h>#include <math.h>intmain(){double x, ret;int n;
    
       x =0.65;
       n =3;
       ret =ldexp(x ,n);printf("%f * 2 %d = %f\n", x, n, ret);return(0);}

    Output

    Run the code and check its output −

    0.650000 * 2^3 = 5.200000
    

    Power and Square Root Functions

    The pow() and sqrt() functions are used to calculate the power and square root of the given number.

    pow() Function

    This function returns x raised to the power of y i.e. xy.

    doublepow(double x,double y)

    sqrt() Function

    returns the square root of x.

    doublesqrt(double x)

    The sqrt(x) function returns a value which is same as pow(x, 0.5)

    Example

    The following example shows how you can use the pow() and sqrt() functions in a C program −

    #include <stdio.h>#include <math.h>intmain(){double x =9, y=2;printf("Square root of %lf is %lf\n", x,sqrt(x));printf("Square root of %lf is %lf\n", x,pow(x,0.5));printf("%lf raised to power %lf\n", x,pow(x, y));return(0);}

    Output

    When you run this code, it will produce the following output −

    Square root of 9.000000 is 3.000000
    Square root of 9.000000 is 3.000000
    9.000000 raised to power 81.000000
    

    Rounding Functions

    The math.h library includes ceil()floor(), and round() functions that round off the given floating point number.

    ceil() Function

    This returns the smallest integer value greater than or equal to x.

    doubleceil(double x)

    This function returns the smallest integral value not less than x.

    floor() Function

    This function returns the largest integer value less than or equal to x.

    doublefloor(double x)

    Parameter x : This is the floating point value. This function returns the largest integral value not greater than x.

    round() Function

    This function is used to round off the double, float or long double value passed to it as a parameter to the nearest integral value.

    doubleround(double x )

    The value returned is the nearest integer represented as floating point

    Example

    The following example demonstrates how you can use the rounding functions in a C program −

    #include <stdio.h>#include <math.h>intmain(){float val1, val2, val3, val4;
    
       val1 =1.2;
       val2 =1.6;
       val3 =2.8;
       val4 =-2.3;printf("ceil(%lf) = %.1lf\n", val1,ceil(val1));printf("floor(%lf) = %.1lf\n", val2,floor(val2));printf("ceil(%lf) = %.1lf\n", val3,ceil(val3));printf("floor(%lf) = %.1lf\n", val4,floor(val4));printf("round(%lf) = %.1lf\n", val1,round(val1));printf("round(%lf) = %.1lf", val4,round(val4));return(0);}
    Output

    When you run this code, it will produce the following output −

    ceil(1.200000) = 2.0
    floor(1.600000) = 1.0
    ceil(2.800000) = 3.0
    floor(-2.300000) = -3.0
    round(1.200000) = 1.0
    round(-2.300000) = -2.0
    

    Modulus Functions

    The “math.h” library includes the following functions in this category:

    modf() Function

    The modf() function returns the fraction component (part after the decimal), and sets integer to the integer component.

    doublemodf(double x,double*integer)

    Here, “x” is the floating point value and “integer” is the pointer to an object where the integral part is to be stored.

    This function returns the fractional part of “x” with the same sign.

    Example

    Take a look at the following example −

    #include <stdio.h>#include <math.h>intmain(){double x, fractpart, intpart;
    
       x =8.123456;
       fractpart =modf(x,&intpart);printf("Integral part = %lf\n", intpart);printf("Fraction Part = %lf \n", fractpart);return(0);}
    Output

    When you run this code, it will produce the following output −

    Integral part = 8.000000
    Fraction Part = 0.123456
    

    fmod() Function

    The fmod() function returns the remainder of x divided by y.

    doublefmod(double x,double y)

    Here, “x” is the numerator and “y” is the denominator. The function returns remainder of “x / y“.

    Example

    Take a look at the following example −

    #include <stdio.h>#include <math.h>intmain(){float a, b;int c;
       a =9.2;
       b =3.7;
       c =2;printf("Remainder of %f / %d is %lf\n", a, c,fmod(a,c));printf("Remainder of %f / %f is %lf\n", a, b,fmod(a,b));return(0);}
    Output

    When you run this code, it will produce the following output −

    Remainder of 9.200000 / 2 is 1.200000
    Remainder of 9.200000 / 3.700000 is 1.800000
    

    Note that the modulus operator (%) works only with integer operands.

  • Command Execution

    Command Execution in C

    Command execution in C is used to execute the system command using the C program. The system commands are executed by using the system() function which is a library function of stdlib.h header file.

    By using the system() function, you can execute the Windows/Linux terminal commands inside a C program.

    Syntax

    The following is the syntax to execute system commands −

    system(char*command);

    Example of Command Execution

    The following code shows the execution of ls command using system() function in C language.

    #include <stdio.h>#include<stdlib.h>#include<string.h>intmain(){char cmd[10];strcpy(cmd,"dir C:\\users\\user\\*.c");system(cmd);return0;}

    Output

    Run the code and check its output −

    C:\Users\user>dir *.c
     Volume in drive C has no label.
     Volume Serial Number is 7EE4-E492
    
     Directory of C:\Users\user
    
    04/01/2024  01:30 PM               104 add.c
    04/02/2024  01:37 PM               159 add1.c
    04/02/2024  01:37 PM               259 array.c
    04/02/2024  01:37 PM               149 main.c
    04/02/2024  01:37 PM               180 recursion.c
    04/02/2024  01:37 PM               241 struct.c
    04/02/2024  01:37 PM               172 voidptr.c
    
               7 File(s)           1,264 bytes
               0 Dir(s)  139,073,761,280 bytes 

    exec Family of Functions in C

    The exec family of functions have been introduced in the “unistd.h” header file. These functions are used to execute a file, and they replace the current process image with a new process image once they are called.

    The following are the functions of exec family in C −

    1. execl() Function
    2. execlp() Function
    3. execle() Function
    4. execv() Function
    5. execvp() Function
    6. execve() Function

    1. execl() Function

    The execl() function’s first argument is the executable file as its first argument. The next arguments will be available to the file when it’s executed. The last argument has to be NULL.

    intexecl(constchar*pathname,constchar*arg,...,NULL)

    Example

    Take a look at the following example −

    #include <unistd.h>intmain(void){char*file ="/usr/bin/echo";char*arg1 ="Hello world!";execl(file, file, arg1,NULL);return0;}

    The echo command in Linux is being invoked through the C code.

    Output

    Save, compile, and execute the above program −

    $ gcc hello.c -o hello
    $ ./hello
    Hello world!
    

    2. execlp() Function

    The execlp() function is similar to the execl() function. It uses the PATH environment variable to locate the file. Hence, the path to the executable file needn’t be given.

    intexeclp(constchar*file,constchar*arg,...,NULL)

    Example

    Take a look at the following example −

    #include <unistd.h>intmain(void){char*file ="echo";char*arg1 ="Hello world!";execlp(file, file, arg1,NULL);return0;}

    Output

    Here, echo is already located in the PATH environment variable. Save, compile and run from the terminal.

    $ gcc hello.c -o hello
    $ ./hello
    Hello world!
    

    3. execle() Function

    In the execle() function, we can pass environment variables to the function, and it’ll use them. Its prototype is like this −

    intexecle(constchar*pathname,constchar*arg,...,NULL,char*const envp[])

    Example

    Take a look at the following example −

    #include <unistd.h>intmain(void){char*file ="/usr/bin/bash";char*arg1 ="-c";char*arg2 ="echo $ENV1 $ENV2!";char*const env[]={"ENV1 = Hello","ENV2 = World",NULL};execle(file, file, arg1, arg2,NULL, env);return0;}

    Output

    Save, compile, and run from the terminal −

    $ gcc hello.c -o hello
    $ ./hello
    Hello world!
    

    4. execv() Function

    The execv() function receives a vector of arguments that will be available to the executable file. In addition, the last element of the vector has to be NULL:

    intexecv(constchar*pathname,char*const argv[])

    Example

    Take a look at the following example −

    #include <unistd.h>intmain(void){char*file ="/usr/bin/echo";char*const args[]={"/usr/bin/echo","Hello world!",NULL};execv(file, args);return0;}

    Output

    Save, compile, and execute the above program −

    $ gcc hello.c -o hello
    $ ./hello
    Hello world!
    

    5. execvp() Function

    The execvp() has the following syntax −

    intexecvp(constchar*file,char*const argv[])

    Example

    Take a look at the following example −

    #include <unistd.h>intmain(void){char*file ="echo";char*const args[]={"/usr/bin/echo","Hello world!",NULL};execvp(file, args);return0;}

    Output

    Save, compile, and execute the above program −

    $ gcc hello.c -o hello
    $ ./hello
    Hello world!
    

    6. execve() Function

    In addition to environment variables, we can pass other arguments to execve() function as a NULL-terminated vector −

    intexecve(constchar*pathname,char*const argv[],char*const envp[])

    Example

    Take a look at the following example −

    #include <unistd.h>intmain(void){char*file ="/usr/bin/bash";char*const args[]={"/usr/bin/bash","-c","echo Hello $ENV!",NULL};char*const env[]={"ENV=World",NULL};execve(file, args, env);return0;}

    Output

    Save, compile, and execute the above program −

    $ gcc hello.c -o hello
    $ ./hello
    Hello world!
    
  • Variable Arguments

    Sometimes, you may come across a situation, when you want to have a function that can accept a variable number of arguments (parameters) instead of a predefined number of arguments. The C programming language provides a solution for this situation.

    Read this chapter to learn how you can define a function that can accept a variable number of parameters based on your requirement.

    The following example shows the definition of such a function −

    intfunc(int,...){......}intmain(){func(1,2,3);func(1,2,3,4);}

    It should be noted that the function func() has its last argument as ellipses, i.e. three dotes (…) and the one just before the ellipses is always an int which will represent the total number variable arguments passed.

    To get such a functionality, you need to use the stdarg.h header file which provides the functions and macros to implement the functionality of variable arguments.

    Follow the steps given below −

    • Define a function with its last parameter as ellipses and the one just before the ellipses is always an int which will represent the number of arguments.
    • Create a va_list type variable in the function definition. This type is defined in stdarg.h header file.
    • Use int parameter and va_start macro to initialize the va_list variable to an argument list. The macro va_start is defined in stdarg.h header file.
    • Use va_arg macro and va_list variable to access each item in argument list.
    • Use a macro va_end to clean up the memory assigned to va_list variable.

    Example

    Let us now follow the above steps and write down a simple function which can take the variable number of parameters and return their average −

    #include <stdio.h>#include <stdarg.h>doubleaverage(int num,...){
    
       va_list valist;double sum =0.0;int i;/* initialize valist for num number of arguments */va_start(valist, num);/* access all the arguments assigned to valist */for(i =0; i < num; i++){
    
      sum +=va_arg(valist,int);}/* clean memory reserved for valist */va_end(valist);return sum/num;}intmain(){printf("Average of 2, 3, 4, 5 = %f\n",average(4,2,3,4,5));printf("Average of 5, 10, 15 = %f\n",average(3,5,10,15));}</code></pre>

    Output

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

    Average of 2, 3, 4, 5 = 3.500000
    Average of 5, 10, 15 = 10.000000
    

    It should be noted that the function average() has been called twice and each time the first argument represents the total number of variable arguments being passed. Only ellipses are used to pass variable number of arguments.

  • Error Handling

    As such, C programming does not provide direct support for error handling, as there are no keywords in C that can prevent errors or exceptions from abruptly terminating the program. However, a programmer can use other functions for error handling.

    You can use errno for efficient error handling in C. Additionally other functions that can be used for error handling include perror, strerror, ferror, and clearererr.

    The errno Variable

    C is a system programming language. It provides you access at a lower level in the form of return values. Most of the C or even Unix function calls return -1 or NULL in case of any error and set an error code errno. It is set as a global variable and indicates an error occurred during any function call. You can find various error codes defined in <error.h> header file.

    So, a C programmer can check the returned values and can take appropriate action depending on the return value. It is a good practice, to set errno to 0 at the time of initializing a program. A value of 0 indicates that there is no error in the program.

    The following table shows the errno values and error messages associated with them −

    errno valueError
    1Operation not permitted
    2No such file or directory
    3No such process
    4Interrupted system call
    5I/O error
    6No such device or address
    7The argument list is too long
    8Exec format error
    9Bad file number
    10No child processes
    11Try again
    12Out of memory
    13Permission denied

    Example

    Take a look at the following example −

    #include <stdio.h>#include <errno.h>intmain(){
    
       FILE* fp;// opening a file which does not exist
       fp =fopen("nosuchfile.txt","r");printf("Value of errno: %d\n", errno);return0;}

    Output

    It will produce the following output −

    Value of errno: 2
    

    The C programming language provides perror() and strerror() functions which can be used to display the text message associated with errno.

    The perror() Function

    displays the string you pass to it, followed by a colon, a space, and then the textual representation of the current errno value.

    voidperror(constchar*str);

    Example

    In the above example, the “errno = 2” is associated with the message No such file or directory, which can be printed with perror() function

    #include <stdio.h>#include <errno.h>intmain(){
    
       FILE* fp;// opening a file which does not exist
       fp =fopen("nosuchfile.txt","r");printf("Value of errno: %d\n", errno);perror("Error message:");return0;}

    Output

    When you run this code, it will produce the following output −

    Value of errno: 2
    Error message: No such file or directory
    

    The strerror() Function

    This returns a pointer to the textual representation of the current errno value.

    char*strerror(int errnum);

    Let us use this function to display the textual representation of errno=2

    Example

    Take a look at the following example −

    #include <stdio.h>#include <errno.h>intmain(){
    
       FILE* fp;// opening a file which does not exist
       fp =fopen("nosuchfile.txt","r");printf("Value of errno: %d\n", errno);printf("The error message is : %s\n",strerror(errno));return0;}

    Output

    Value of errno: 2
    he error message is : No such file or directory
    

    The ferror() Function

    This function is used to check whether an error occurred during a file operation.

    intferror(FILE *stream);

    Example

    Here, we try to read from a file opened in w mode. The ferror() function is used to print the error message

    #include <stdio.h>intmain(){
    
       FILE *fp;
       fp =fopen("test.txt","w");char ch =fgetc(fp);// Trying to read data, from writable fileif(ferror(fp)){printf("File is opened in writing mode! You cannot read data from it!");}fclose(fp);return(0);}

    Output

    Run the code and check its output −

    File is opened in writing mode! You cannot read data from it!
    

    The clearerr() Function

    The clearerr() function is used to clear both end-of-file and error indicators for a file stream.

    voidclearerr(FILE *stream);

    Example

    Take a look at the following example −

    #include <stdio.h>intmain(){
    
       FILE *fp;
       fp =fopen("test.txt","w");char ch =fgetc(fp);// Trying to read data, from writable fileif(ferror(fp)){printf("File is opened in writing mode! You cannot read data from it!\n");}// Clears error-indicators from the file stream // Subsequent ferror() doesn't show errorclearerr(fp);if(ferror(fp)){printf("Error again in reading from file!");}fclose(fp);return(0);}

    Divide by Zero Errors

    It is a common problem that at the time of dividing any number, programmers do not check if a divisor is zero and finally it creates a runtime error.

    Example 1

    The following code fixes this error by checking if the divisor is zero before dividing −

    #include <stdio.h>#include <stdlib.h>intmain(){int dividend =20;int divisor =0;int quotient;if( divisor ==0){fprintf(stderr,"Division by zero! Exiting...\n");exit(-1);}
       quotient = dividend / divisor;fprintf(stderr,"Value of quotient : %d\n", quotient );exit(0);}

    Output

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

    Division by zero! Exiting...
    Program Exit Status
    

    It is a common practice to exit with a value of EXIT_SUCCESS in case of program coming out after a successful operation. Here, EXIT_SUCCESS is a macro and it is defined as 0.

    Example 2

    If you have an error condition in your program and you are coming out then you should exit with a status EXIT_FAILURE which is defined as “-1”. So let’s write the above program as follows −

    #include <stdio.h>#include <stdlib.h>intmain(){int dividend =20;int divisor =5;int quotient;if(divisor ==0){fprintf(stderr,"Division by zero! Exiting...\n");exit(EXIT_FAILURE);}
    
       quotient = dividend / divisor;fprintf(stderr,"Value of quotient: %d\n", quotient );exit(EXIT_SUCCESS);}

    Output

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

    Value of quotient: 4