FOP Practice Final
FOP Practice Final
PROGRAMMING PRACTICE
Table of Contents
FUNDAMENTALS OF PROGRAMMING PRACTICE....................................................................1
I. INTRODUCTION.............................................................................................................................3
II. ALGORITHMS...............................................................................................................................3
II.1.1. Qualities of a good algorithm...........................................................................................3
II.1.2 Real life Example..............................................................................................................4
II.1.3. Programming Examples of Algorithm:............................................................................4
II. 2. FLOW CHAT.............................................................................................................................10
II.2.1 Definition:............................................................................................................................10
III. C PROGRAMMING....................................................................................................................11
III.1. TOOLS TO BE USED IN THIS PRACTICE COURSE......................................................11
III.2. PROGRAMMING CULTURE AND ADVICE....................................................................11
Variables.........................................................................................................................................14
Literals...........................................................................................................................................15
1. Integers..................................................................................................................................15
2. Floating-point Literals...........................................................................................................15
3. Characters..............................................................................................................................15
5. String Literals........................................................................................................................15
Rules for naming a variable......................................................................................................16
III.3. LOCAL VARIABLES..........................................................................................................17
III.3.1 Local Scope or Block Scope..........................................................................................17
III.4. Global Variables....................................................................................................................17
III.4.1 Global Scope..................................................................................................................17
III.5. Constant Types in C..............................................................................................................18
Integer Constant........................................................................................................................19
Real constant.............................................................................................................................20
Single Character Constants.......................................................................................................20
String Constants........................................................................................................................20
Backslash character constant.....................................................................................................20
Example.........................................................................................................................................22
III.6. DATA TYPES IN C LANGUAGE.......................................................................................22
III.6.1 Primary data types..........................................................................................................22
III.6.2 Derived data types..........................................................................................................23
III.7 STRINGS...............................................................................................................................27
III.7.1. How to initialize strings?..............................................................................................27
III.7.2. Read String from the user.............................................................................................28
III.7.3. Passing Strings to Function...........................................................................................29
III.7.4. String Manipulations Functions(Important to know)....................................................31
III.8. ARRAY SORTING...............................................................................................................31
III.8.1. Bubble Sort...................................................................................................................31
III.8.2. Selection Sort................................................................................................................37
III.8.3. Insertion Sort.................................................................................................................42
III.9. POINTER VARIABLES.......................................................................................................47
III.9.1. Address in C..................................................................................................................47
III.9.2. How to create a pointer variable?..................................................................................48
III.9.3. Pointer access and errors...............................................................................................50
III.9.4. Strings and Pointers......................................................................................................52
III.9.5. Benefits of using pointers.............................................................................................53
III.10. STRUCTURES...................................................................................................................53
III.10.1. How to define a structure?..........................................................................................53
III.10.2. Syntax of structure......................................................................................................53
III.10.3. Create structure variable.............................................................................................54
III.10.4. How to Access members of a structure?.....................................................................55
III.10.5. Keyword typedef In C.................................................................................................57
III.10.6. Nested Structures........................................................................................................59
III.11. UNIONS.............................................................................................................................61
III.11.1. Accessing a Union Member........................................................................................63
III.12. FUNCTION IN C...............................................................................................................64
III.12.1. Function Declarations.................................................................................................64
III.12.2. Calling a Function.......................................................................................................65
III.12.2. Function arguments and return values........................................................................65
III.13. RECURSION......................................................................................................................72
III.13.1. Recursion Vs Iteration?...............................................................................................75
III.14. PATTERNS PROGRAMMING..........................................................................................77
III.15. FILES IN C.........................................................................................................................84
III.15.1. Types of Files..............................................................................................................84
III.15.2. File Operations............................................................................................................85
III.15.3. Working with files.......................................................................................................85
III.15.4. Files Opening Modes in Standard I/O.........................................................................86
III.15.5. Closing a File..............................................................................................................87
III.15.6. Reading and writing to a text file................................................................................87
III.15.7. Reading and writing to a binary file............................................................................89
III.15.7.1. Writing to a binary file.............................................................................................89
III.15.8 Finding/Getting data using fseek()...............................................................................92
III.16. TYPE CASTING IN...........................................................................................................95
III.16.1. Implicit conversion.....................................................................................................96
III.16. 2. Explicit conversion....................................................................................................96
III.17. DYNAMIC MEMORY ALLOCATION IN C....................................................................97
III.17.1. Allocating block of Memory.......................................................................................98
III.18. SOCKET PROGRAMMING IN C...................................................................................100
TCP (Transmission control protocol)......................................................................................101
Client-server communication Sequential Diagram(Flow chart diagram)..........................102
Steps in algorithm to create a client using TCP/IP API..........................................................102
Steps in algorithm to create a server using TCP/IP API.........................................................102
Create a socket........................................................................................................................108
Connect socket to a server.......................................................................................................108
Send data over socket..............................................................................................................110
Receive data on socket............................................................................................................111
Close socket.............................................................................................................................113
Get ip address of hostname.....................................................................................................113
Socket server...........................................................................................................................114
Bind socket to a port................................................................................................................115
Listen for incoming connections on the socket.......................................................................115
Accept connection...................................................................................................................116
Live Server..............................................................................................................................119
Handle multiple socket connections with threads...................................................................120
III.19. Error Handling in C..........................................................................................................124
IV. Introduction to data Structures....................................................................................................127
V. C and DBMSes.............................................................................................................................132
V.1. About MySQL database........................................................................................................133
C99...............................................................................................................................................133
v.2 First example..........................................................................................................................133
V.3 Creating a database................................................................................................................134
V.4. Creating and populating a table............................................................................................136
V.5. Retrieving data from the database........................................................................................138
V.6. Last inserted row id..............................................................................................................140
V.7. Column headers....................................................................................................................142
V.8. Multiple statements..............................................................................................................143
V.9. Inserting images into MySQL database................................................................................145
V.10. Selecting images from MySQL database...........................................................................149
V. INDEX: Practical Exercises.........................................................................................................151
I. INTRODUCTION
This document is a reference to the Syllabus of this course, only focusing on
practice of the bellow four main items:
1. Algorithms
2. Flowchart
3. Programming in C
4. Programming in C++
II. ALGORITHMS
An Algorithm specifies a series of steps that performs a particular
computation or task. It is a step by step procedure of solving a problem.
It were originally born as part of mathematics from the Arabic writer
Muḥammad ibn Mūsā al-Khwārizmī, and now strongly associated with
computer science. A good algorithm mean an efficient solution to be
developed.
Pseudo code :
If a>b
If a>c
print” a is the largest number”;
Else
print” c is the largest number”;
Else
If b>c
print” b is the largest number”;
Else
print” c is the greatest number”;
Then you have to teach the computer : My God ! Really ? Does Software
engineers teach the computer how to solve problems ? Yes they Do !!
To make good progress in your programming task, you need to test your work
as early and as thoroughly as possible. Everybody makes mistakes while
programming and finding mistakes in programs consumes a very large part of a
programmer’s work-day. Finding a problem in a small and easy piece of code is
much simpler than trying to spot it in a large program. This is why you should
try to test each sub task you identified during your task-breakdown by itself.
Only after you’re confident that each part works as you expect you can attempt
to plug them together. Make sure you test the complete program as well, errors
can creep in in the way the different parts interact. You should try to automate
your tests. The easier it is to test your program, the freer you are in
experimenting with changes.
The last important point is how you express your thoughts as code. In the same
way that you can express the same argument in different ways in a normal
English essay, you can express the same problem-solving method in different
ways in your codes.
Understandable codes is key to success.
Remember that you don’t write the program for the computer, you write it for
other humans (maybe a future you!). Choose variable names that explain
things, add comments where these names don’t suffice. Never comment on
what the code is doing, only write comments that explain why was the code
written.
Better naming and a better task breakdown make the comments obsolete.
Revise your code just as you would revise an essay. Sketch, write, delete,
reformulate, ask others what they think. Ahahahah!! Nowadays GOOGLE is
our best friend, GOOGLE IT PLEASE if you can’t do it on your own!.
Repeat until only the crispest possible expression of your idea remains. Revisit
code you’ve written a while ago to see whether you can improve it with things
you’ve learned since.
Look at the famous Hello world program.
#include <stdio.h>
/*
My first program in c
I wish I could like this languages
*/
int main(){
// Where can I write my Hello world text ?
printf("Hello, World !\n");
// wawoo!!, I have written to the console,OK!
return 0;
}
-printf()
The printf() is a library function to send formatted output to the screen.
In this program, the printf() displays Hello, World! text on the screen.
- return 0
The return 0; statement is the "Exit status" of the program. In simple terms,
program ends with this statement.
-{}
the open and closed braces are to mark the start and the end of the main
function
- // and /* */: Comments
Anything following the "//" symbols is a comment and it can not be executed by
the compiler, it is part of our program but just for humans not for the computer.
Please use // in you programs if you are talking of few thing
or other comments in case you want to be talkative:
/*
Any thing put here is a comment and can not be executed, the compiler will not
care of how big was the text in comments!!!.
*/
Variables
1. Integers
An integer is a numeric literal(associated with numbers) without any fractional
or exponential part. There are three types of integer literals in C programming:
decimal (base 10)
octal (base 8)
hexadecimal (base 16)
For example:
Decimal: 0, -9, 22 etc
Octal: 021, 077, 033 etc
Hexadecimal: 0x7f, 0x2a, 0x521 etc
2. Floating-point Literals
A floating-point literal is a numeric literal that has either a fractional form or an
exponent form. For example:
-2.0
0.0000234
-0.22E-5
3. Characters
A character literal is created by enclosing a single character inside single
quotation marks. For example: 'a', 'm', 'F', '2', '}' etc;
5. String Literals
1. A variable name can have only letters (both uppercase and lowercase
letters), digits and underscore.
2. The first letter of a variable should be either a letter or an underscore.
3. There is no rule on how long a variable name (identifier) can be.
However, you may run into problems in some compilers if the variable
name is longer than 31 characters.
Note: You should always try to give meaningful names to variables. For
example: firstName is a better variable name than fn or fname.
C is a strongly typed language. This means that the variable type cannot be
changed once it is declared. For example:
int number = 5; // Good
Here, the type of number variable is int. You cannot assign a floating-point
(decimal) value 5.5 to this variable. Also, you cannot redefine the data type of
the variable to double. By the way, to store the decimal values in C, you need
to declare its type to either double or float.
Variable’s scope
A scope is a region of the program, and the scope of variables refers to the
area of the program where the variables can be accessed after their
declarations.
In C, every variable is defined in a scope. You can define scope as the section
or region of a program where a variable has its existence; moreover, that
variable cannot be used or accessed beyond that region, this make sens, yes.
In C programming, a variable declared within a function is different from a
variable declared outside of a function. The variable can be declared in three
places/regions. These are:
Variable Position Type / named as
Inside a function or a
local variables
block of code.
Out of all functions. Global variables
In the function Formal parameters
parameters.
If you want to define a variable whose value cannot be changed, you can
constants.
For example,
const float PI = 3.14;
PI = 2.9; //Error
#define val 10
#define floatVal 4.5
#define charVal 'G'
int main()
{
printf("Integer Constant: %d\n",val);
printf("Floating point Constant: %.1f\n",floatVal);
printf("Character Constant: %c\n",charVal);
return 0;
}
Integer Constant
It's referring to a sequence of digits. Integers are of three types viz:
1. Decimal Integer
2. Octal Integer
3. Hexadecimal Integer
Example:
15, -265, 0, 99818, +25, 045, 0X6
Real constant
The numbers containing fractional parts like 99.25 are called real or floating
points constant.
String Constants
These are a sequence of characters enclosed in double quotes, and they may
include letters, digits, special characters, and blank spaces. It is again to be
noted that "G" and 'G' are different - because "G" represents a string as it is
enclosed within a pair of double quotes whereas 'G' represents a single
character.
Example:
"Hello!", "2015", "2+1"
Secondary Constant
Array
Pointer
Structure
Union
Enumulation
Enumulation in C
int main()
{
// int constant
const int intVal = 10;
// Real constant
const float floatVal = 4.14;
// char constant
const char charVal = 'A';
// string constant
const char stringVal[10] = "ABC";
return 0;
}
III.5.4. Enumerations
Enumeration is a user defined datatype in C language. It is used to assign
names to the integral constants which makes a program easy to read and
maintain. The keyword “enum” is used to declare an enumeration. They are
mainly used to assign names to integral constants, the names make a program
easy to read and maintain.
Here is the syntax of enum in C language,
enum enum_name{const1, const2, ....... };
The enum keyword is also used to define the variables of enum type. There
are two ways to define the variables of enum type as follows.
enum week{sunday, monday, tuesday, wednesday, thursday, friday, saturday};
enum week day;
Example
#include<stdio.h>
int main() {
return 0;
}
Data types specify how we enter data into our programs and what type of data
we enter. C language has some predefined set of data types to handle various
kinds of data that we can use in our program. These datatypes have different
storage capacities.
C language supports 2 different type of data types: ayayayaaa types of
type ????
III.6.2.1 Arrays
An array is a collection of a fixed number of values of a single type. For
example: if you want to store 100 integers in a sequence, you can create an
array for it. It what ? That data type …….. for example :
int data[100]; uhhh you can’t get it by now.
OK, the above statement states that :”data” is a variable capable of storing
one hundreds numbers !!! So, it behaves like a collection of a hundred
variables of same type int? Yes.
The size and type of arrays cannot be changed after its declaration.
Arrays are of two types:
1. One-dimensional arrays
2. Multidimensional arrays
For example, if we want an array of six integers (or whole numbers), we write:
int numbers[6]; and for a six character array called letters:,
char letters[6];
and so on.
You can also initialize as you declare. Just put the initial elements in curly
brackets separated by commas as the initial value:
type name[number of elements]={my comma-separated values}, please
not that values in an array are coma separated right ? Coma Separated !
For example, if we want to initialize an array with six integers, with 0, 0, 1, 0, 0,
0 a s the initial values then we will easily do it as bellow:
int point[6]={0,0,1,0,0,0}; very simple!
Though when the array is initialized as in this case, the array dimension may be
omitted, and the array will be automatically sized to hold the initial
data,interesting that the size of an array can dynamically be determined at run
time:
int point[]={0,0,1,0,0,0};
This is very useful in that the size of the array can be controlled by simply
adding or removing initialized elements from the definition without the need to
adjust the dimension(size).
If the dimension is specified, but not all elements in the array are initialized,
the remaining places will contain a default value of that data type like 0 in the
above case of integers. This is very useful, especially when we have very large
arrays.
int numbers[2000]={25};
The above example sets the first value of the array of numbers to 25, and the
rest to 0.s , Uhhuuhhh it sounds resource wasting.
How to initialize an array?
It's possible to initialize an array during declaration. For example,
float marks[5] = {19, 10, 8, 17, 9};
Arrays in C are indexed starting at 0, as opposed to starting at 1 in real life
counting. The first element of the array above is marks[0]. The index to the last
value in the array is the array size minus one. In the example above the
subscripts run from 0 through 5. C does not guarantee bounds checking on
array accesses. T
Array Elements access
You can access elements of an array by indices( indexes ?).
Suppose you declared an array points as bellow. The first element is points[0],
second element is points[1] and so on until when you reach the 5th element.
The compiler may not complain about the following (though the best compilers
do):
char point[6] = { 1, 2, 3, 4, 5, 6 };
//examples of accessing outside the array. A compile error is not always raised
y = point[15]; // the array index out of bound is not thrown but really the error
has occurred
y = point[-4]; // the array index out of bound is not thrown but really the error
has occurred
y = point[z]; // the array index out of bound is not thrown but really the error
has occurred
Note: Your program will run but actually it is erroneous, so unexpected results.
If we want to access a variable stored in an array, for example with the above
declaration, the following code will store a 1 in the variable x
int x;
x = point[2];
During program execution, an out of bounds array access does not always
cause a run time error. Your program may happily continue after retrieving a
value from point[-1]. To alleviate indexing problems, the sizeof() expression is
commonly used when coding loops that process arrays.
Many people use a macro that in turn uses sizeof() to find the number of
elements in an array, a macro variously named
"lengthof()","MY_ARRAY_SIZE()" or
"NUM_ELEM()","SIZEOF_STATIC_ARRAY()",etc.
int ix;
short anArray[]= { 3, 567, 9, 12, 15 };
char two_d[3][5];
int two_d[2][3] = {
{ 5, 2, 1 }, // row one has three columns
{ 6, 7, 8 } // row two has three columns
};
The amount of columns must be explicitly stated; however, the compiler will
find the appropriate amount of rows based on the initialized list.
There are also weird notations possible:
int a[100];
int i = 0;
if (a[i]==i[a])
{
printf("Hello world!\n");
}
a[i] and i[a] refer to the same location. (This is explained later in the next
Chapter.)
III.7 STRINGS
How to declare a string?
Before you can work with strings, you need to declare them first. Since string is
an array of characters. You declare strings in a similar way like you do with
character arrays.
Here's how you declare a string s:
char s[5];
You can use the scanf() function from the stdio library to read a string.
The scanf() function reads the sequence of characters until it encounters a
whitespace (space, newline, tab etc.) and stops there.
#include <stdio.h>
int main()
{
char name[20];
printf("Enter name: ");
scanf("%s", name);
printf("Your name is %s.", name);
return 0;
}
Output:
Enter name: Dennis Ritchie
Your name is Dennis. // This output is questionable no?
Even though Dennis Ritchie was entered in the above program, only "Dennis"
was stored in the name string. It's because there was a space after Dennis.
int main(){
char str[50];
printf("Enter string: ");
gets(str);
displayString(str); // Passing string to a function.
return 0;
}
void displayString(char str[])
{
printf("The passed String was: ");
puts(str);
}
C has no string handling facilities built in; consequently, strings are defined as
arrays of characters; I repeat as arrays of characters OK. C allows a
character array to be represented as a character string rather than a list of
characters, good! With the null terminating character automatically added to
the end. For example, to store the string "MUKAJISTOS", we would write
char string[10] = "MUKAJISTOS";
or
char string[10] = {'M', 'U', 'K', 'A', 'J', 'I', 'S', 'T', 'O', 'S', '\0'};
In the first example, the string will have a null character ('\0') automatically
appended to the end by the compiler; by convention, library functions expect
strings to be terminated by a null character ('\0'). The latter declaration
indicates individual elements, and as such the null terminator ('\0') needs to be
added manually.
Strings do not always have to be linked to an explicit variable. As you have
seen already, a string of characters can be created directly as an unnamed
string that is used directly (as with the printf functions.)
To create an extra long string, you will have to split the string into multiple
sections, by closing the first section with a quote, and recommencing the string
on the next line (also starting and ending in a quote):
char string[58] = "This is a very, very long " "string that requires two
lines.";
While strings may also span multiple lines by putting the backslash character
at the end of the line, this method is deprecated.
There is a useful library of string handling routines which you can use by
including another header file.
This standard string library will allow various tasks to be performed on strings.
III.7.4. String Manipulations Functions(Important to know)
Functi
Work of Function
on
strlen() Calculates the length of string
strcpy() Copies a string to another string
strcat() Concatenates(joins) two strings
strcmp(
Compares two string
)
strlwr() Converts string to lowercase
strupr() Converts string to uppercase
Computers are designed to quickly and merrily accomplish boring tasks, such
as sorting an array. In fact, they love doing it so much that “the sort” is a
basic computer concept upon which many theories and algorithms have been
written.
The simplest sort is the bubble sort, which not only is easy to explain and
understand but also has a fun name(Bubble Sort). It also best shows the basic
array-sorting philosophy, which is to swap values between two elements. Goog
now we all know what sorting is really about!! It is about swapping elements:
SIMPLE
Sorting takes place by stepping through all the elements one-by-one and
comparing it with the adjacent element and swapping them if required.
Implementing Bubble Sort Algorithm
Following are the steps involved in bubble sort(for sorting a given array in
ascending order):
1. Starting with the first element(index = 0), compare the current element
with the next element of the array.
2. If the current element is greater than the next element of the array, swap
them.
3. If the current element is less than the next element, move to the next
element. Repeat Step 1.
Let's consider an array with values {5, 1, 6, 2, 4, 3}
Below, we have a pictorial representation of how bubble sort will sort the given
array.
So as we can see in the representation above, after the first iteration, 6 is
placed at the last index, which is the correct position for it.
Similarly after the second iteration, 5 will be at the second last index, and so
on.
#include <stdio.h>
// Defining the function to handle the sorting
void bubbleSort(int arr[], int n)
{
int array[]={some unsorted elements};
int i, j, temp;
for(i = 0; i < n; i++)
{
for(j = 0; j < n-i-1; j++)
{
if( array[j] > array[j+1])
{
// swap the elements
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
// print the sorted array
printf("Sorted Array: ");
for(i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
}
int main()
{
int array[100], i, n, step, temp;
// ask user for number of elements to be sorted
printf("Enter the number of elements to be sorted: ");
scanf("%d", &n);
return 0;
}
If for a particular iteration, no swapping took place, it means the array has
been sorted and we can jump out of the for loop, instead of executing all the
iterations.
Let's consider an array with values {11, 17, 18, 26, 23}
Below, we have a pictorial representation of how the optimized bubble sort will
sort the given array.
As we can see, in the first iteration, swapping took place, hence we updated
our flag value to 1, as a result, the execution enters the for loop again. But in
the second iteration, no swapping will occur, hence the value of flag will remain
0, and execution will break out of loop.
// below we have a simple C program for improved bubble sort
#include <stdio.h>
void bubbleSort(int arr[], int n)
{
int array[]={some unsorted elements};
int i, j, temp;
for(i = 0; i < n; i++)
{
for(j = 0; j < n-i-1; j++)
{
// introducing a flag to monitor swapping
int flag = 0;
if( array[j] > array[j+1])
{
// swap the elements
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
// if swapping happens update flag to 1
flag = 1;
}
}
// if value of flag is zero after all the iterations of inner loop
// then break out
if(!flag)
{
break;
}
}
// print the sorted array
printf("Sorted Array: ");
for(i = 0; i < n; i++)
{
printf("%d ", arrray[i]);
}
}
int main()
{
int array[100], i, n, step, temp;
// ask user for number of elements to be sorted
printf("Enter the number of elements to be sorted: ");
scanf("%d", &n);
// input elements in the array one by one
for(i = 0; i < n; i++)
{
printf("Enter element no. %d: ", i+1);
scanf("%d", &array[i]);
}
// call the function bubbleSort
bubbleSort(array, n);
return 0;
}
In the above code, in the function bubbleSort, if for a single complete cycle of j
iteration(inner for loop), no swapping takes place, then flag will remain 0 and
then we will break out of the for loops, because the array has already been
sorted.
Following are the steps involved in selection sort(for sorting a given array in
ascending order):
1. Starting from the first element, we search the smallest element in the
array, and replace it with the element in the first position.
2. We then move on to the second position, and look for smallest element
present in the sub array, starting from index 1, till the last index.
3. We replace the element at the second position in the original array, or
we can say at the first position in the sub array, with the second smallest
element.
4. This is repeated, until the array is completely sorted.
In the C program below, we have tried to divide the program into small
functions, so that it's easier for you to understand which part is doing what.
There are many different ways to implement selection sort algorithm, here is
the one that we like:
}
// the function that prints the content of any size array
void printArray(int array[], int size)
{
int i;
for(i = 0; i < size; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
int main()
{
int array[] = {46, 52, 21, 22, 11};
int n = sizeof(arr)/sizeof(arr[0]);
selectionSort(array, n);
printf("Sorted array: \n");
printArray(array, n);
return 0;
}
Note: Selection sort is an unstable sort i.e it might change the occurrence of
two similar elements in the list while sorting. But it can also work as a stable
sort when it is implemented using linked list. Oohh my God yoyoooo !! what
are those Linked lists? I wish you wait until when you do the course of data
structures and algorithms, I like C programming almost everything was
thought of..
III.8.3. Insertion Sort
Consider you have 10 cards out of a deck of cards in your hand. And they are
sorted, or arranged in the ascending order of their numbers.
If I give you another card, and ask you to insert the card in just the right
position, so that the cards in your hand are still sorted. What will you do?
Well, let me guess : “ you will have to go through each card from the starting or
the back and find the right position for the new card, comparing it's value with
each card” Right ? . Ok, Once you find the right position, you will insert the
card there,Voila ! You have done insertion, but is it an insertion sort ?
Similarly, if more new cards are provided to you, you can easily repeat the
same process and insert the new cards and keep the cards sorted too.
This is exactly how insertion sort works. It starts from the index 1(not 0), and
each index starting from index 1 is like a new card, that you have to place at
the right position in the sorted sub array on the left.
#include <stdio.h>
//member functions declaration
void insertionSort(int array[], int length);
void printArray(int array[], int size);
// main function
int main()
{
int array[5] = {5, 1, 6, 2, 4, 3};
// calling insertion sort function to sort the array
insertionSort(array, 6);
return 0;
}
Now let's try to understand the above simple insertion sort algorithm.
We took an array with 6 integers. We took a variable key, in which we put each
element of the array, during each pass, starting from the second element, that
is a[1].
Then using the while loop, we iterate, until j becomes equal to zero or we find
an element which is greater than key, and then we insert the key at that
position.
We keep on doing this, until j becomes equal to zero, or we encounter an
element which is smaller than the key, and then we stop. The current key is
now at the right position.
We then make the next element as key and then repeat the same process.
In the above array, first we pick 1 as key, we compare it with 5(element before
1), 1 is smaller than 5, we insert 1 before 5. Then we pick 6 as key, and
compare it with 5 and 1, no shifting in position this time. Then 2 becomes the
key and is compared with 6 and 5, and then 2 is inserted after 1. And this goes
on until the complete array gets sorted.
III.9. POINTER VARIABLES
III.9.1. Address in C
Before you get into the concept of pointers, let's first get familiar with address
in C.
If you have a variable var in your program, &var will give you its address in the
memory, where & is commonly called the reference operator.
You must have seen this notation while using scanf() function. It was used in
the function to store the user inputted value in the address of var, I know you
have already seen it the magic “&”.
#include <stdio.h>
int main()
{
int var = 5;
printf("Value: %d\n", var);
printf("Address: %u", &var); //Notice, the ampersand(&) before var.
return 0;
}
Output
Value: 5
Address: 2686778
Note: You may obtain different value of address while using this code.
In above source code, value 5 is stored in the memory location 2686778. var is
just the name given to that location.
In C, you can create a special variable that stores the address (rather than the
value). This variable is called a : “pointer variable” or simply a: ”pointer” .
III.9.2. How to create a pointer variable?
data_type * pointer_variable_name;
int * p;
Above statement defines, p as pointer variable of type int.
#include <stdio.h>
int main()
{
int * pc, c;
c = 22;
printf("Address of c: %u\n", &c);
printf("Value of c: %d\n\n", c);
pc = &c;
printf("Address of pointer pc: %u\n", pc);
printf("Content of pointer pc: %d\n\n", *pc);
c = 11;
printf("Address of pointer pc: %u\n", pc);
printf("Content of pointer pc: %d\n\n", *pc);
// a pointer can change the valu of a variable
*pc = 2;
printf("Address of c: %u\n", &c);
printf("Value of c: %d\n\n", c);
return 0;
}
Output
Address of c: 2686784
Value of c: 22
Address of c: 2686784
Value of c: 2
5. *pc = 2;
int a = 5;
int *ptr = NULL;
Addres
Contents
s
0x813 0x000000
0 05
0x813 0x000000
4 00
(The NULL pointer shown here is 0x00000000.) By assigning the address of a to
ptr:
ptr = &a;
yields the following memory values:
Address Contents
0x8130 0x00000005
0x8134 0x00008130
Clearly, accessing a will yield the value of 8 because the previous instruction
modified the contents of a by way of the pointer ptr.
Common mistakes when working with pointers
Suppose, you want pointer pc to point to the address of c. Then,
int c, *pc;
// Wrong! pc is address whereas,
// c is not an address.
pc = c;
// Wrong! *pc is the value pointed by address whereas,
// &c is an address.
*pc = &c;
// Correct! pc is an address and,
// &c is also an address.
ptr = &a;
// Correct! * ptr is the value pointed by address and,
// c is also a value (not address).
*pc = c;
Similarly like arrays, string names are "decayed" to pointers. Hence, you can
use pointer with the same name as string to manipulate elements of the string.
#include <stdio.h>
int main(void) {
char name[] = "Harry Potter"; // A string initialization as a character array
char *namePtr;
namePtr = name;
printf("%c", *namePtr); // Output: H
printf("%c", *(namePtr+1)); // Output: a
printf("%c", *(namePtr+7)); // Output: o
}
III.10. STRUCTURES
struct Person
{
char name[50];
int citNo;
float salary;
}person0;
int main()
{
struct Person person1, person2, persons[20]; // variable declaration
using Person structure
return 0;
}
Another way of creating a structure variable is:
struct Person
{
char name[50];
int citNo;
float salary;
} person1, person2, persons[20];
There are two types of operators used for accessing members of a structure.
1. Member operator(.)
2. Structure pointer operator(->) (this will be discussed in structure and
pointers)
Suppose, you want to access salary of person2. Here's how you can do it:
person2.salary // Very simple
Example:
// Program to add two distances which is in feet and inches
#include <stdio.h>
struct Distance
{
int feet;
float inch;
} dist1, dist2, sum;
int main()
{
printf("1st distance\n");
printf("Enter feet: ");
scanf("%d", &dist1.feet);
printf("Enter inch: ");
scanf("%f", &dist1.inch);
printf("2nd distance\n");
// adding feet
sum.feet = dist1.feet + dist2.feet;
// adding inches
sum.inch = dist1.inch + dist2.inch;
int main() {
structure Distance d1, d2;
}
is equivalent to
typedef struct Distance{
int feet;
float inch;
} distances;
int main() {
distances d1, d2, sum; // declaring variable using typedof
}
Application of typedef
typedef can be used to give a name to user defined data type as well. Lets see
its use with structures.
typedef struct
{
type member1;
type member2;
type member3;
} type_name;
Here type_name represents the structure definition associated with it. Now
this type_name can be used to declare a variable of this structure type.
type_name t1, t2;
void main( )
{
emp e1;
printf("\nEnter Employee record:\n");
printf("\nEmployee name:\t");
scanf("%s", e1.name);
printf("\nEnter Employee salary: \t");
scanf("%d", &e1.salary);
printf("\nstudent name is %s", e1.name);
printf("\nroll is %d", e1.salary);
}
typedef and Pointers
typedef can be used to give an alias name to pointers also. Here we have a
case in which use of typedef is beneficial during pointer declaration.
In Pointers * binds to the right and not on the left.
int* x, y;
By this declaration statement, we are actually declaring x as a pointer of type
int, whereas y will be declared as a plain int variable. Not clear! I know, but its
OK.
typedef int* IntPtr; define an IntPtr type that can be used to declare pointers
without the use of the magic dereference operator (*) .
Ckeck bellow :
IntPtr x, y, z;
But if we use typedef like we have used in the example above, we can declare
any number of pointers in a single statement.
What? x, y and z are pointers without a * ? Wawoooooooo !!!!!!!!!!!!
Yes the are!
struct number
{
struct complex comp;
int integers;
} num1, num2;
Suppose, you want to set imag of num2 variable to 11. Here's how you can do
it:
num2.comp.imag = 11;
The arrow operator (->) is used to access the members of the structure using
pointer to structure.
For example, if we want to access member name, and ptr is the pointer to
structure. The statement to access name will be ptr->name.
C Example program for pointer to structure
#include <stdio.h>
//structure definition
struct student{
char name[50];
int age;
int rollno;
};
//main function
int main(){
//pointer to structure declaration
struct student *ptr;
return 0;
}
III.11. UNIONS
This declares a variable It1 of type union item. This union contains three
members each with a different data type. However only one of them can be
used at a time. This is due to the fact that only one memory location is
allocated for all the union variables, irrespective of their size. The compiler
allocates the storage that is large enough to hold the largest variable type in
the union.
In the union declared above the member x requires 4 bytes which is largest
among-st the members for a 16-bit machine. Other members of union will
share the same memory address.
III.11.1. Accessing a Union Member
Syntax for accessing any union member is similar to accessing structure
members,
union test
{
int a;
float b;
char c;
}t;
#include <stdio.h>
union item
{
int a;
float b;
char ch;
};
int main( )
{
union item it;
it.a = 12;
printf("%d\n", it.a);
it.b = 20.2;
printf("%f\n", it.b);
it.ch = 'z';
printf("%c\n", it.ch);
// Checking for corruption in memory
printf("%d\n", it.a);
printf("%f\n", it.b);
printf("%c\n", it.ch);
return 0;
}
Corrupted output:
-26426 20.1999 z
As you can see here, the values of a and b get corrupted and only variable c
prints the expected result z. This is because in union, the memory is shared
among different data types. Hence, the only member whose value is currently
stored will have the memory.
In the above example, value of the variable c “Z”was stored at last, hence the
values of other variables were lost.
III.12. FUNCTION IN C
A function declaration tells the compiler about a function name and how to
call the function. The actual body of the function can be defined separately.
A function declaration has the following parts −
return_type function_name( parameter list );
For the above defined function max(), the function declaration is as follows −
int max(int num1, int num2);
Parameter names are not important in function declaration only their type is
required, so the following is also a valid declaration −
int max(int, int);
Function declaration is required when you define a function in one source file
and you call that function in another file. In such case, you should declare the
function at the top of the file calling the function.
Types of function:
In C programming language we has two types of functions:
Predefined function or Library Function, “C” provides some function
which are created by its own library. that’s why these functions are also
called library functions . these functions are declared in the header file
like- scanf(), printf(), gets(), puts(), ceil(), floor() etc.
User defined function , “C” provides the facility like the other
languages to create the function according to the situation by the
programmer. user defined functions reduces the complexity of a big
program and complexity of code.
Function definition :
void function()
{
statements;
}
#include <stdio.h>
// Function declaration
void value(void);
void main()
{
value();
}
// Function definition
void value(void)
{
int year = 1, period = 5, amount = 5000, inrate = 0.12;
float sum;
sum = amount;
while (year <= period) {
sum = sum * (1 + inrate);
year = year + 1;
}
printf(" The total amount is %f:", sum);
}
Output:
The total amount is 5000.000000
void myFunction(int a, )
{
}
printf("\nvalue of str is %s\n", ??????????????);
}
Function with no arguments but returns a value : There could be
occasions where we may need to design functions that may not take any
arguments but returns a value to the calling function. A example for this is
getchar function it has no parameters but it returns an integer an integer type
data that represents a character.
Syntax :
Function declaration : int function();
Function call : function();
Function definition :
int function()
{
statements;
return x;
}
int sum();
int main()
{
int num;
num = sum();
printf("\nSum of two given values = %d", num);
return 0;
}
int sum()
{
int a = 50, b = 80, sum;
sum = sqrt(a) + sqrt(b);
return sum;
}
Output:
Sum of two given values = 16
#include <stdio.h>
#include <string.h>
int myFunction(int a);
int main()
{
int result= myFunction(10);
int myFunction(int a)
{
int i=0;
a=a+i;
return a;
}
Output:
value of a is 40
III.13. RECURSION
The recursion continues until some condition is met to prevent it from calling
its selves again.
To prevent infinite recursion, if...else statement (or similar approach) can be
used where one branch makes the recursive call and other doesn't.
int main()
{
int number, result;
printf("Enter a positive integer: ");
scanf("%d", &number);
result = sum(number);
Initially, the sum() is called from the main() function with number passed as an
argument.
Suppose, the value of num is 3 initially. During next function call, 2 is passed
to the sum() function. This process continues until num is equal to 0.
When num is equal to 0, the if condition fails and the else part is executed
returning the sum of integers to the main() function.
Advantages and Disadvantages of Recursion
Recursion makes program elegant and more readable. However, if performance
is vital then, use loops instead as recursion is usually much slower.
Note that, every recursion can be modeled into a loop.
III.13.1. Recursion Vs Iteration?
Need performance, use loops, however, code might look ugly and hard to read
sometimes. Need more elegant and readable code, use recursion, however,
you are sacrificing some performance. Now you know both its up to you to let
us know how a good programming analyst you are.
#include <stdio.h>
void main()
{
int i, fact = 1, num;
printf("Enter the number \n");
scanf("%d", &num);
if (num <= 0)
fact = 1;
else
{
for (i = 1; i <= num; i++)
{
fact = fact * i;
}
} printf("Factorial of %d = %5d\n", num, fact);
}
Factorial Program Explanation
In this C program, we are reading the integer number using ‘num’ integer
variable. A factorial is a product of all the numbers from 1 to n, where n is the
user specified number.
If condition statement is used to check the value of ‘num’ variable is less than
or equal to 0. If the condition is true then it will execute the statement and
assign the value of ‘fact’ variable as one. Otherwise, if the condition is false
then it will execute the else statement. Using for loop multiply all the numbers
from 1 to n and display the factorial of a given number as output.
int main()
{
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
printf("Factorial of %d = %ld", n, multiplyNumbers(n));
return 0;
}
long int multiplyNumbers(int n)
{
if (n >= 1)
return n*multiplyNumbers(n-1);
else
return 1;
}
III.14. PATTERNS PROGRAMMING
This the art of writing programs that generate various patterns of numbers and
stars or of any symbols. Such programs involve usage of nested for loops (a for
loop inside a for loop). A pattern of numbers, star or characters is a way of
arranging these in some logical manner or they may form a sequence. Some of
these patterns are triangles which have special importance in mathematics.
Some patterns are symmetrical while others are not.
Pattern : 1
*****
*****
*****
*****
* * * * *_
Program : 1
#include <stdio.h>
//#include <conio.h>
void main() {
int i,j;
//clrscr();
for (i=0; i<5; i++) {
for (j=0; j<5; j++) {
printf(" * ");
}
printf("\n"); }
//getch();
}
Pattern : 2
*
**
***
****
* * * * *_
Program : 2
#include <stdio.h>
void main() {
int i,j;
Pattern : 3
*
**
***
****
* * * * *_
Program : 3
#include <stdio.h>
void main() {
int i,j,k;
for (i=1; i<=5; i++) {
for (j=5; j>=i; j--) {
printf(" ");
}
for (k=1; k<=i; k++) {
printf("*");
}
printf("\n");
}
Pattern : 4
*****
****
***
**
*_
Program : 4
#include <stdio.h>
void main() {
int i,j,k,samp=1;
}
Pattern : 5
*****
****
***
**
*_
Program : 5
#include <stdio.h>
void main() {
int i,j;
for (i=5; i>=1; i--) {
for (j=1; j<=i; j++) {
printf(" * ");
}
printf("\n");
}
Pattern : 6
*
**
***
****
* * * * *_
Program : 6
#include <stdio.h>
void main() {
int i,j,k,t=0;
for (i=1; i<=5; i++) {
for (k=t; k<5; k++) {
printf(" ");
}
for (j=0; j< i; j++) {
printf(" * ");
t = t + 1;
}
printf("\n");
}
Pattern : 7
*
**
***
****
*****
****
***
**
*_
Program : 7
#include <stdio.h>
void main() {
int i,j,k,samp=1;
Output : 9
Enter number of rows: 5
0
101
21012
3210123
432101234
5 4 3 2 1 0 1 2 3 4 5_
Program : 9
#include <stdio.h>
void main() {
int no,i,y,x=35;
for (y=0;y<=no;y++) {
goto(x,y+1);
for (i=0-y; i<=y; i++) {
printf(" %3d ", abs(i));
x=x-3;
}
}
}
Output : 10
1
22
333
4444
55555
Program : 10
#include <stdio.h>
void main() {
int i, j=5, k, x;
for (i=1;i<=5;i++) {
for (k=1;k<=j;k++) {
printf(" ");
}
for (x=1;x<=i;x++) {
printf("%d",i);
printf(" ");
}
printf("\n");
j=j-1;
}
}
III.15. FILES IN C
1. Text files
Text files are the normal .txt files that you can easily create using Notepad or
any simple text editors.
When you open those files, you'll see all the contents within the file as plain
text. You can easily edit or delete the contents.
They take minimum effort to maintain, are easily readable, and provide least
security and takes bigger storage space.
2. Binary files
Binary files are mostly the .bin files in your computer.
Instead of storing data in plain text, they store it in the binary form (0's and
1's).
They can hold higher amount of data, are not readable easily and provides a
better security than text files.
When working with files, you need to declare a pointer of type file. This
declaration is needed for communication between the file and program.
FILE *fptr; // file pointer declaration
The file (both text and binary) should be closed after reading/writing.
Closing a file is performed using library function fclose().
fclose(fptr); //fptr is the file pointer associated with file to be closed.
For reading and writing to a text file, we use the functions fprintf() and
fscanf().
They are just the file versions of printf() and scanf(). The only difference is
that, fprint and fscanf expects a pointer to the structure FILE.
int main()
{
int num;
FILE *fptr;
fptr = fopen("C:\\program.txt","w");
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
fprintf(fptr,"%d",num);
fclose(fptr);
return 0;
}
This program takes a number from user and stores in the file program.txt.
After you compile and run this program, you can see a text file program.txt
created in C drive of your computer. When you open the file, you can see the
integer you entered.
fscanf(fptr,"%d", &num);
return 0;
}
This program reads the integer present in the program.txt file and prints it onto
the screen.
If you successfully created the file from Example 1, running this program will
get you the integer you entered.
Other functions like fgetchar(), fputc() etc. can be used in similar way.
To write into a binary file, you need to use the function fwrite(). The functions
takes four arguments: Address of data to be written in disk, Size of data to be
written in disk, number of such type of data and pointer to the file where you
want to write.
fwrite(address_data,size_of_data,numbers_of_record_data,pointer_to_file);
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
if ((fptr = fopen("C:\\program.bin","wb")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
for(n = 1; n < 5; ++n)
{
num.n1 = n;
num.n2 = 5*n;
num.n3 = 5*n + 1;
fwrite(&num, sizeof(struct threeNum), 1, fptr);
}
fclose(fptr);
return 0;
}
In this program, you create a new file program.bin in the C drive if we are on
windows, but on linux the directory will be any of you choice.
We declare a structure threeNum with three numbers - n1, n2 and n3, and
define it in the main function as num.
Now, inside the for loop, we store the value into the file using fwrite().
The first parameter takes the address of num and the second parameter takes
the size of the structure threeNum.
Since, we're only inserting one instance of num, the third parameter is 1. And,
the last parameter *fptr points to the file we're storing the data.
Finally, we close the file.
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
return 0;
}
In this program, you read the same file program.bin and loop through the
records one by one.
In simple terms, you read one threeNum record of threeNum size from the file
pointed by *fptr into the structure num.
You'll get the same records you inserted in Example 3.
III.15.8 Finding/Getting data using fseek()
If you have many records inside a file and need to access a record at a specific
position, you need to loop through all the records before it to get the record.
This will waste a lot of memory and operation time. An easier way to get to the
required data can be achieved using fseek().
As the name suggests, fseek() seeks the cursor to the given record in the file.
Whence Meaning
SEEK_SET Starts the offset from the beginning of the file.
SEEK_END Starts the offset from the end of the file.
Starts the offset from the current location of the cursor in the
SEEK_CUR
file.
Example 5: fseek()
#include <stdio.h>
#include <stdlib.h>
struct threeNum
{
int n1, n2, n3;
};
int main()
{
int n;
struct threeNum num;
FILE *fptr;
return 0;
}
This program will start reading the records from the file program.bin in the
reverse order (last to first) and prints it.
III.15.8.3. Examples:
fptr = fopen("file.txt","wb");
for(i = 0; i < 5; ++i)
{
fflush(stdin);
printf("Enter name: ");
gets(stud1[i].name);
Type casting is a way to convert a variable from one data type to another data
type. For example, if you want to store a long value into a simple integer then
you can typecast long to int. You can convert values from one type to another
explicitly using the cast operator. There are two types of type casting in c
language that are Implicit conversions and Explicit Conversions. In this article,
we also learn about the difference between type casting and type conversions.
It is best practice to convert lower data type to higher data type to
avoid data loss Data will be truncated when the higher data type is converted
to lower. For example, if a float is converted to int, data which is present after
the decimal point will be lost.
1 Implicit Conversion
2 Explicit Conversion
Example :
#include<stdio.h>
void main(){
int i=20;
double p;
p=i; // implicit conversion
printf(“implicit value is %d”,p);
}
Here, the value of a has been promoted from int to double and we have not had to specify
any type-casting operator. This is known as a standard conversion.
Global variables, static variables and program instructions get their memory
in permanent storage area whereas local variables are stored in a memory
area called Stack.
The memory space between these two region is known as Heap area. This
region is used for dynamic memory allocation during execution of the program.
The size of heap keep changing.
III.17.1. Allocating block of Memory
malloc() function is used for allocating block of memory at run time. This
function reserves a block of memory of the given size and returns a pointer of
type void. This means that we can assign it to any type of pointer using
typecasting. If it fails to allocate enough space as specified, it returns a NULL
pointer.
Syntax:
void* malloc(byte-size)
Syntax:
void * calloc(number of items, element-size)
int main()
{
int i, n;
int *element;
/*
returns a void pointer(which is type-casted to int*)
pointing to the first block of the allocated space
*/
element = (int*) calloc(n,sizeof(int));
/*
If it fails to allocate enough space as specified,
it returns a NULL pointer.
*/
if(element == NULL)
{
printf("Error.Not enough space available");
exit(0);
}
Before we start our couse, keep in mind that this concept works well on Linux
OS environment than it will in windows, but its OK for our windows guys we will
evolve together, that's cool I guess.
Seeking time usage maximization our leaning will focus on socket
programming using TCP/IP because it is the most used internet protocol
involved in programming, but researchers will go father and do UDP. UDP; a
right weight data transfer protocol, it is connection-less.
TCP (Transmission control protocol)
int SocketCreate(void)
{
int hSocket;
printf("Create the socket\n");
return iRetval;
}
//Create socket
socket_desc = SocketCreate();
if (socket_desc == -1)
{
printf("Could not create socket");
return 1;
}
printf("Socket created\n");
//Bind
if( BindCreatedSocket(socket_desc) < 0)
{
//print the error message
perror("bind failed.");
return 1;
}
printf("bind done\n");
//Listen
listen(socket_desc , 3);
while(1)
{
if(strcmp(pMessage,client_message)==0)
{
close(sock);
sleep(1);
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
//Create a Socket for server communication
short SocketCreate(void)
{
short hSocket;
printf("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket;
}
int iRetval=-1;
int ServerPort = 90190;
struct sockaddr_in remote={0};
// Send the data to the server and set the timeout of 20 seconds
int SocketSend(int hSocket,char* Rqst,short lenRqst)
return shortRetval;
}
}
shortRetval = recv(hSocket, Rsp , RvcSize , 0);
printf("Response %s\n",Rsp);
return shortRetval;
}
//Create socket
hSocket = SocketCreate();
if(hSocket == -1)
{
printf("Could not create socket\n");
return 1;
}
printf("Socket is created\n");
close(hSocket);
shutdown(hSocket,0);
shutdown(hSocket,1);
shutdown(hSocket,2);
return 0;
}
dddddddddddd
Create a socket
This first thing to do is create a socket. The socket function does this.
Here is a code sample :
#include<stdio.h>
#include<sys/socket.h>
int main()
{
int socket_desc;
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
return 0;
}
Function socket() creates a socket and returns a descriptor which can be used
in other functions. The above code will create a socket with following properties
Address Family - AF_INET (this is IP version 4)
Type - SOCK_STREAM (this means connection oriented TCP protocol)
Protocol - 0 [ or IPPROTO_IP This is IP protocol]
Note
Apart from SOCK_STREAM type of sockets there is another type called
SOCK_DGRAM which indicates the UDP protocol. This type of socket is non-
connection socket. In this tutorial we shall stick to SOCK_STREAM or TCP
sockets.
struct in_addr {
unsigned long s_addr; // load with inet_pton()
};
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
The sockaddr_in has a member called sin_addr of type in_addr which has a
s_addr which is nothing but a long. It contains the IP address in long format.
Function inet_addr is a very handy function to convert an IP address to a long
format. This is how you do it :
server.sin_addr.s_addr = inet_addr("74.125.235.20");
So you need to know the IP address of the remote server you are connecting to.
Here we used the ip address of google.com as a sample. A little later on we
shall see how to find out the ip address of a given domain name.
The last thing needed is the connect function. It needs a socket and a
sockaddr structure to connect to. Here is a code sample.
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("74.125.235.20");
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
puts("Connected");
return 0;
}
It cannot be any simpler. It creates a socket and then connects. If you run the
program it should show Connected.
Try connecting to a port different from port 80 and you should not be able to
connect which indicates that the port is not open for connection.
OK , so we are now connected. Lets do the next thing , sending some data to
the remote server.
Connections are present only in tcp sockets
The concept of "connections" apply to SOCK_STREAM/TCP type of sockets.
Connection means a reliable "stream" of data such that there can be multiple
such streams each having communication of its own. Think of this as a pipe
which is not interfered by other data.
Other sockets like UDP , ICMP , ARP dont have a concept of "connection".
These are non-connection based communication. Which means you keep
sending or receiving packets from anybody and everybody.
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("74.125.235.20");
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
puts("Connected\n");
return 0;
}
In the above example , we first connect to an ip address and then send the
string message "GET / HTTP/1.1\r\n\r\n" to it.
The message is actually a http command to fetch the mainpage of a website.
Now that we have send some data , its time to receive a reply from the server.
So lets do it.
Note
When sending data to a socket you are basically writing data to that socket.
This is similar to writing data to a file. Hence you can also use the write
function to send data to a socket. Later in this tutorial we shall use write
function to send data.
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("74.125.235.20");
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
return 0;
}
Data Send
Reply received
We can see what reply was send by the server. It looks something like Html,
well IT IS html. Google.com replied with the content of the page we requested.
Quite simple!
Note
When receiving data on a socket , we are basically reading the data on the
socket. This is similar to reading data from a file. So we can also use the read
function to read data on a socket. For example :
read(socket_desc, server_reply , 2000);
Now that we have received our reply, its time to close the socket.
Close socket
Function close is used to close the socket. Need to include the unistd.h header
file for this.
close(socket_desc);
Thats it.
Your web browser also does the same thing when you open
www.google.com
This kind of socket activity represents a socket client. A client is an
application that connects to a remote system to fetch or retrieve data.
The other kind of socket application is called a socket server. A server is a
system that uses sockets to receive incoming connections and provide them
with data. It is just the opposite of Client. So www.google.com is a server
and your web browser is a client. Or more technically www.google.com is a
HTTP Server and your web browser is an HTTP client.
Now its time to do some server tasks using sockets. But before we move ahead
there are a few side topics that should be covered just in case you need them,
or you have missed my previous explanations.
The h_addr_list has the IP addresses. So now lets have some code to use
them.
#include<stdio.h>; //printf
#include<string.h>; //strcpy
#include<sys/socket.h>;
#include<netdb.h>; //hostent
#include<arpa/inet.h>;
//Cast the h_addr_list to in_addr , since h_addr_list also has the ip address in long format
only
addr_list = (struct in_addr **) he->;h_addr_list;
So the above code can be used to find the ip address of any domain name.
Then the ip address can be used to make a connection using a socket.
Function inet_ntoa will convert an IP address ifrom long format to dotted
format. This is just the opposite of inet_addr.
So far we have seen some important structures that are used. Lets revise
them :
1. sockaddr_in - Connection information. Used by connect , send , recv etc.
2. in_addr - Ip address in long format
3. sockaddr: The super structure for address definition
4. hostent - The ip addresses of a hostname. Used by gethostbyname
In the next part we shall look into creating servers using socket. Servers are
the opposite of clients, that instead of connecting out to others, they wait
for incoming connections.
Socket server
OK now onto server things. Socket servers operate in the following manner:
1. Open a socket
2. Bind to a address(and port).
3. Listen for incoming connections.
4. Accept connections
5. Read(receive) / write(Send)
We have already learnt how to open a socket. So the next thing would be to
bind it.
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf(";Could not create socket";);
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts(";bind failed";);
}
puts(";bind done";);
Now that binding is done, its time to make the socket listen to connections.
We bind a socket to a particular IP address and a certain port number. By
doing this we ensure that all incoming data which is directed towards this port
number is received by this application(our server).
This makes it obvious that you cannot have 2 sockets bound to the same
port.
After binding a socket to a port the next thing we need to do is listen for
connections. For this we need to put the socket in listening mode. Function
listen is used to put the socket in listening mode. Just add the following line
after bind.
//Listen
listen(socket_desc , 3);// this server can listen to 3 and only three connections ata same time
That’s all. Now comes the main part of accepting new connections.
Accept connection
The accept function is used for this. Here is the code
#include<stdio.h>;
#include<sys/socket.h>;
#include<arpa/inet.h>; //inet_addr
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf(";Could not create socket";);
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts(";bind failed";);
}
puts(";bind done";);
//Listen
listen(socket_desc , 3);
puts(";Connection accepted";);
return 0;
}
Program output
Run the program. It should show
bind done
Waiting for incoming connections...
So now this program is waiting for incoming connections on port 8888. Dont
close this program , keep it running, ok. It is a server right ? Servers never
stop running !!!!!!
Now a client can connect to our server on the port. We shall use the telnet
client for testing this. Open a terminal and type
$ telnet localhost 8888 // this mean terminal client is connecting to the server
So we can see that the client connected to the server. Try the above process till
you get it perfect, till you fell confident of doing it you self, it is not simple but it
is doable.
Get the ip address of the connected client
You can get the ip address of client and the port of connection by using the
sockaddr_in structure passed to accept function. It is very simple :
char *client_ip = inet_ntoa(client.sin_addr);
int client_port = ntohs(client.sin_port);
Here is an example :
#include<stdio.h>;
#include<string.h>; //strlen
#include<sys/socket.h>;
#include<arpa/inet.h>; //inet_addr
#include<unistd.h>; //write
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf(";Could not create socket";);
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts(";bind failed";);
return 1;
}
puts(";bind done";);
//Listen
listen(socket_desc , 3);
puts(";Connection accepted";);
return 0;
}
Run the above code in 1 terminal. And connect to this server using telnet from
another terminal and you should see this :
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello Client , I have received your connection. But I have to go now, bye
Connection closed by foreign host.
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf(“Could not create socket”;);
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts(";bind failed";);
return 1;
}
puts(";bind done";);
//Listen
listen(socket_desc , 3);
if (new_socket<0)
{
perror(";accept failed";);
return 1;
}
return 0;
}
We haven’t done a lot there. Just the accept was put in a loop.
Hahahah; this lmagic lopp will make our server to run indefinitly, hence a
live server
Now run the program in 1 terminal , and open 3 other terminals. From each of
the 3 terminal do a telnet to the server port.
Each of the telnet terminal would show :
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello Client , I have received your connection. But I have to go now, bye
So now the server is running nonstop and the telnet terminals are also
connected nonstop. Now close the server program.
All telnet terminals would show "Connection closed by foreign host."
Good so far. But still there is not effective communication between the server
and the client.
The server program accepts connections in a loop and just send them a reply,
after that it does nothing with them. Also it is not able to handle more than 1
connection at a time. So now its time to handle the connections , and handle
multiple connections together.
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf(";Could not create socket";);
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts(";bind failed";);
return 1;
}
puts(";bind done";);
//Listen
listen(socket_desc , 3);
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts(";Handler assigned";);
}
if (new_socket<0)
{
perror(";accept failed";);
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
char *message;
return 0;
}
Run the above server and open 3 terminals like before. Now the server will
create a thread for each client connecting to it. Intersting and advenced; I
will come back to this after completing multhreading in java in the coming
year, do not be worried.
The telnet terminals would show :
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello Client , I have received your connection. And now I will assign a handler for you
Hello I am your connection handler
Its my duty to communicate with you
This one looks good , but the communication handler is also quite dumb. After
the greeting it terminates. It should stay alive and keep communicating with
the client.
One way to do this is by making the connection handler wait for some message
from a client as long as the client is connected. If the client disconnects , the
connection handler ends.
So the connection handler can be rewritten like this :
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
message = ";Now type something and i shall repeat what you type \n";;
write(sock , message , strlen(message));
if(read_size == 0)
{
puts(";Client disconnected";);
fflush(stdout);
}
else if(read_size == -1)
{
perror(";recv failed";);
}
return 0;
}
The above connection handler takes some input from the client and replies
back with the same. Simple! Here is how the telnet output might look
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello Client , I have received your connection. And now I will assign a handler for you
Greetings! I am your connection handler
Now type something and i shall repeat what you type
Hello
Hello
How are you
How are you
I am fine
I am fine
Generally sendto() and recvfrom() are used to send/receive UDP data grams
without explicit connection initiation. This is UDP protocal you did in
networking course.
The server will mostly use bind() to listen on an opened port but may fail much
more likely than listen(), so in our program we have decided to use both of
them first bind the listen.
In Windows we will only care of:
1. Use different set of header files - windows.h plus winsock.h
2. Remember to initialize socket library - WSAStartup()
3. Use send() and recv() rather than write() and read()
4. Call closesocket() instead of close()
Of course, in real life examples things get not so simple, but with these hints
any hard worker will make it if need be.
C language does not provide any direct support for error handling. However a
few methods and variables defined in error.h header file can be used to point
out error using the return statement in a function. In C language, a function
returns -1 or NULL value in case of any error and a global variable errno is set
with the error code. So the return value can be used to check error while
programming.
What is errno?
Whenever a function call is made in C language, a variable named errno is
associated with it. It is a global variable, which can be used to identify which
type of error was encountered while function execution, based on its value.
Below we have the list of Error numbers and what does they mean.
Error no Error value
1 Operation not permitted
2 No such file or directory
3 No such process
4 Interrupted system call
5 I/O error
6 No such device or address
7 Argument list too long
8 Exec format error
9 Bad file number
10 No child processes
11 Try again
12 Out of memory
13 Permission denied
Example:
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main ()
{
FILE *fp;
/*
If a file, which does not exists, is opened,
we will get an error
*/
fp = fopen("IWillReturnError.txt", "r");
printf("Value of errno: %d\n ", errno);
printf("The error message is : %s\n", strerror(errno));
perror("Message from perror");
return 0;
}
Value of errno: 2 The error message is: No such file or directory Message from
perror: No such file or directory
Other ways of Error Handling
We can also use Exit Status constants in the exit() function to inform the
calling function about the error. The two constant values available for use are
EXIT_SUCCESS and EXIT_FAILURE. These are nothing but macros defined in
the stdlib.h header file, they are just numbers like 0 and 1.
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char *ptr = malloc( 1000000000UL); //requesting to allocate 1gb memory
space
if (ptr == NULL) //if memory not available, it will return null
{
puts("malloc failed");
puts(strerror(errno));
exit(EXIT_FAILURE); //exit status failure
}
else
{
free( ptr);
exit(EXIT_SUCCESS); //exit status Success
}
}
Here exit function is used to indicate exit status. Its always a good practice to
exit a program with a exit status. EXIT_SUCCESS and EXIT_FAILURE are two
macro used to show exit status. In case of program coming out after a
successful operation EXIT_SUCCESS is used to show successful exit. It is
defined as 0. EXIT_Failure is used in case of any failure in the program. It is
defined as -1.
Division by Zero
There are some situation where nothing can be done to handle the error. In C
language one such situation is division by zero. All you can do is avoid doing
this, because if you do so, C language is not able to understand what
happened, and gives a run time error.
Best way to avoid this is, to check the value of the divisor before using it in the
division operations. You can use if condition, and if it is found to be zero, just
display a message and return from the function.
The entry point into a linked list is always the first node or
head of the list. It should be noted that head is NOT a
separate node, but a reference to the first Node in the list. If
the list is empty, then the head has the value NULL, ie not head
available and obviously no linked list available, there can not
be any linked list without a head node.
Unlike Arrays, nodes cannot be accessed by an index since
memory allocated for each individual node may not be
continuous. We must begin from the head of the list and
traverse the list sequentially to access the nodes in the list.
Insertions of new nodes and deletion of existing nodes are fairly
easy to handle and will be discussed in the this lesson. Recall
that array insertions or deletions may require adjustment of the
array (overhead), but insertions and deletions in linked lists can
be performed very efficiently.
IV.2. Types of Linked Lists
A doubly linked list is a list that has two references, one to the
next node and another to previous node. Doubly linked list also
starts from head node, but provide access both ways. That is
one can traverse forward or backward from any node.
For example, a struct Node that contains an int data field and
a pointer to another node can be defined as follows:
struct Node {
int data;
struct Node* next;
}
typedef struct Node node;
node* head = NULL;
(*head).data = 10;
(*head).next = NULL;
Drawbacks:
A linked list is represented by a pointer to the first node of the linked list. The
first node is called the head. If the linked list is empty ie non existing !!!!,
then the value of the head is NULL.
Each node in a list consists of at least two parts:
1) Data
2) Pointer (Or Reference) to the next node.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
int main()
{
// allocate 3 nodes in the heap memory
return 0;
}
V. C and DBMSes
V.1. About MySQL database
MySQL is a leading open source database management system. It is a multi
user, multi threaded database management system. MySQL is especially
popular on the web. It is one part of the very popular LAMP platform consisting
of Linux, Apache, MySQL, and PHP. MySQL currently owned by Oracle. MySQL
database is available on most important OS platforms. It runs on BSD Unix,
Linux, Windows, or Mac OS. Wikipedia and YouTube use MySQL. These sites
manage millions of queries each day. MySQL comes in two versions: MySQL
server system and MySQL embedded system.
Configure the mysql:
to configure the mysql libraries you just have to run the bellow command:
$ sudo apt-get install libmysqlclient-dev
C99
This tutorial uses C99. For GNU C compiler, we need to add the -std=c99
option. For Windows users, the Pelles C IDE is highly recommended. (MSVC
does not support C99.)
MYSQL *con = mysql_init(NULL);
In C99, we can mix declarations with code. In older C programs, we would need
to separate this line into two lines.
exit(0);
}
We include necessary header files. The mysql.h is the most important header
file for MySQL function calls. The my_global.h includes some global
declarations a functions. Among other things, it includes the standard
input/output header file, very nice.
printf("MySQL client version: %s\n", mysql_get_client_info());
This code line outputs the version of the MySQL client. For this, we use the
mysql_get_client_info() function call.
exit(0);
Example output.
if (con == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
The code example connects to the MySQL database system and creates a new
database called testdb.
MYSQL *con = mysql_init(NULL);
We check the return value. If the mysql_init() function fails, we print the error
message and terminate the application.
if (mysql_real_connect(con, "localhost", "root", "root_pswd",
NULL, 0, NULL, 0) == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
The mysql_query() executes the SQL statement. In our case, the statement
creates a new database.
mysql_close(con);
The second example already utilizes features from C99 standard. Therefore, we
need to add the -std=c99 option.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| testdb |
+--------------------+
3 rows in set (0.00 sec)
if (con == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
mysql_close(con);
exit(0);
}
We don't use any new MySQL function call here. We use mysql_query() function
call to both create a table and insert data into it.
void finish_with_error(MYSQL *con)
{
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
if (con == NULL)
{
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
if (result == NULL)
{
finish_with_error(con);
}
MYSQL_ROW row;
mysql_free_result(result);
mysql_close(con);
exit(0);
}
We execute the query that will retrieve all data from the Cars table.
MYSQL_RES *result = mysql_store_result(con);
We get the result set using the mysql_store_result() function. The MYSQL_RES is
a structure for holding a result set.
int num_fields = mysql_num_fields(result);
Example output.
char *sql = "CREATE TABLE Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name TEXT)";
if (mysql_query(con, sql))
{
finish_with_error(con);
}
int id = mysql_insert_id(con);
mysql_close(con);
exit(0);
}
A new table is created. Three rows are inserted into the table. We determine
the last inserted row id.
char *sql = "CREATE TABLE Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name TEXT)";
if (con == NULL)
{
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
if (result == NULL)
{
finish_with_error(con);
}
MYSQL_ROW row;
MYSQL_FIELD *field;
printf("\n");
}
printf("\n");
mysql_free_result(result);
mysql_close(con);
exit(0);
}
We print the first three rows from the Cars table. We also include the column
headers.
MYSQL_FIELD *field;
printf("\n");
}
The first row contains the column headers. The mysql_fetch_field() call returns
a MYSQL_FIELD structure. We get the column header names from this structure.
$ ./headers
Id Name Price
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
if (con == NULL)
{
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
do {
MYSQL_RES *result = mysql_store_result(con);
if (result == NULL)
{
finish_with_error(con);
}
printf("%s\n", row[0]);
mysql_free_result(result);
status = mysql_next_result(con);
if (status > 0) {
finish_with_error(con);
}
} while(status == 0);
mysql_close(con);
exit(0);
}
The last option of the mysql_real_connect() method is the client flag. It is used
to enable certain features. The CLIENT_MULTI_STATEMENTS enables the
execution of multiple statements. This is disabled by default.
if (mysql_query(con, "SELECT Name FROM Cars WHERE Id=2;\
SELECT Name FROM Cars WHERE Id=3;SELECT Name FROM Cars WHERE Id=6"))
{
finish_with_error(con);
}
The query consists of three SELECT statements. They are separated by the
semicolon ; character. The backslash character \ is used to separate the string
into two lines. It has nothing to do with multiple statements.
do {
...
} while(status == 0);
The code is placed between the do/while statements. The data retrieval is to be
done in multiple cycles. We will retrieve data for each SELECT statement
separately.
status = mysql_next_result(con);
Example output.
For our examples, we create a new Images table. The image size can be up to
16 MB. It is determined by the MEDIUMBLOB data type.
#include <my_global.h>
#include <mysql.h>
#include <string.h>
if (fp == NULL)
{
fprintf(stderr, "cannot open image file\n");
exit(1);
}
fseek(fp, 0, SEEK_END);
if (ferror(fp)) {
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
exit(1);
}
if (flen == -1) {
perror("error occurred");
int r = fclose(fp);
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
exit(1);
}
fseek(fp, 0, SEEK_SET);
if (ferror(fp)) {
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
exit(1);
}
char data[flen+1];
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
exit(1);
}
int r = fclose(fp);
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
if (con == NULL)
{
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
char chunk[2*size+1];
mysql_real_escape_string(con, chunk, data, size);
mysql_close(con);
exit(0);
}
In this example, we will insert one image into the Images table.
#include <string.h>
if (fp == NULL)
{
fprintf(stderr, "cannot open image file\n");
exit(1);
}
Here we open the image file. In the current working directory, we should have
the woman.jpg file.
fseek(fp, 0, SEEK_END);
if (ferror(fp)) {
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
exit(1);
}
We move the file pointer to the end of the file using the fseek() function. We
are going to determine the size of the image. If an error occurs, the error
indicator is set. We check the indicator using the fseek() function. In case of an
error, we also close the opened file handler.
int flen = ftell(fp);
if (flen == -1) {
perror("error occurred");
int r = fclose(fp);
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
exit(1);
}
For binary streams, the ftell() function returns the number of bytes from the
beginning of the file, e.g. the size of the image file. In case of an error, the
function returns -1 and the errno is set. The perrro() function interprets the
value of errno as an error message, and prints it to the standard error output
stream.
char data[flen+1];
We read the data from the file pointer and store it in the data array. The total
number of elements successfully read is returned.
int r = fclose(fp);
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
Here we start building the SQL statement. We determine the size of the SQL
string using the strlen() function.
char query[st_len + 2*size+1];
int len = snprintf(query, st_len + 2*size+1, st, chunk);
The query must take be long enough to contain the size of the SQL string
statement and the size of the image file. Using the snprintf() function, we write
the formatted output to query buffer.
if (mysql_real_query(con, query, len))
{
finish_with_error(con);
};
if (fp == NULL)
{
fprintf(stderr, "cannot open image file\n");
exit(1);
}
if (con == NULL)
{
fprintf(stderr, "mysql_init() failed\n");
exit(1);
}
if (result == NULL)
{
finish_with_error(con);
}
if (lengths == NULL) {
finish_with_error(con);
}
if (ferror(fp))
{
fprintf(stderr, "fwrite() failed\n");
mysql_free_result(result);
mysql_close(con);
exit(1);
}
int r = fclose(fp);
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
mysql_free_result(result);
mysql_close(con);
exit(0);
}
if (ferror(fp))
{
fprintf(stderr, "fwrite() failed\n");
mysql_free_result(result);
mysql_close(con);
exit(1);
}
We write the retrieved data to the disk using the fwrite() function call. We
check for the error indicator with the ferror() function.
int r = fclose(fp);
if (r == EOF) {
fprintf(stderr, "cannot close file handler\n");
}
After we have written the image data, we close the file handler using the
fclose() function.
13. Write a guessing game where the user has to guess a secret
number. After every guess the program tells the user whether their
number was too large or too small. At the end the number of tries needed
should be printed. It counts only as one try if they input the same number
multiple times consecutively.
14. Write a program that prints the next 20 leap years.
15. Write a function that returns the largest number in a collection n
positive of numbers.
16. Write a simple calculator program that can perform all 4 basic
mathematical operation and print the result. Lets the program be able to
only accept numbers as user inputs and reject any other data type.
17. Write three functions that compute the sum of the numbers in a
list: using a for-loop, a while-loop and recursion.
18. Write a function that computes the list of the first 100 Fibonacci
numbers. The first two Fibonacci numbers are 1 and 1. The n+1-st
Fibonacci number can be computed by adding the n-th and the n-1-th
Fibonacci number. The first few are therefore 1, 1, 1+1=2, 1+2=3,
2+3=5, 3+5=8.
19. Write a function that takes a number and returns a list of its digits.
So for 2342 it should return [2,3,4,2].
20. Write a function that takes a list of strings an prints them, one per
line, in a rectangular frame. For example the list ["Hello", "World", "in",
"a", "frame"] gets printed as:
*********
* Hello *
* World *
* in *
*a *
* frame *
*********
18 . Write function that translates a text to Pig Latin and back. English is
translated to Pig Latin by taking the first letter of every word, moving it to the
end of the word and adding ‘ay’. “The quick brown fox” becomes “Hetay
uickqay rownbay oxfay”
19. Write a program that outputs all possibilities to put + or - or nothing
between the numbers 1,2,…,9 (in this order) such that the result is 100. For
example 1 + 2 + 3 - 4 + 5 + 6 + 78 + 9 = 100.
20. Write a program that takes the duration of a year (in fractional days) for an
imaginary planet as an input and produces a leap-year rule that minimizes the
difference to the planet’s solar year.
30. C program to add two distances in feet and inches using structure.
Pictorial Presentation:
REGULAR EXPRESSIONS in C:
https://www.regular-expressions.info/email.html