Unit 2
Arrays and strings
An array is a collection of data items, all of the same type, accessed using a common name.
A one-dimensional array is like a list; A two dimensional array is like a table; The C language places no limits on the number of dimensions in an array, though specific implementations may.
Some texts refer to one-dimensional arrays as vectors, two-dimensional arrays as matrices, and use the general term arrays when the number of dimensions is unspecified or unimportant.
Declaring Arrays
Array variables are declared identically to variables of their data type, except that the variable name is followed by one pair of square [ ] brackets for each dimension of the array.
Uninitialized arrays must have the dimensions of their rows, columns, etc. listed within the square brackets.
Dimensions used when declaring arrays in C must be positive integral constants or constant expressions.
In C99, dimensions must still be positive integers, but variables can be used, so long as the variable has a positive value at the time the array is declared. ( Space is allocated only once, at the time the array is declared. The array does NOT change sizes later if the variable used to declare it changes. )
Examples:
Inti, j, intArray[ 10 ], number;
Float floatArray[ 1000 ];
InttableArray[ 3 ][ 5 ]; /* 3 rows by 5 columns */
Const int NROWS = 100; // ( Old code would use #define NROWS 100 )
Const int NCOLS = 200; // ( Old code would use #define NCOLS 200 )
Float matrix[ NROWS ][ NCOLS ];
String:
The abstract model of string is implemented by defining a character array data type and we need to include header file ‘string.h’, to hold all the relevant operations of string. The string header file enables user to view complete string and perform various operation on the string. E.g. We can call ‘strlen’ function to find length of string, ‘strcat’ to concatenate two string, ‘strcpy’ to copy one string to another, ‘strrev’ to reverse the string. The definitions of all these functions are stored in the header file ‘string.h’. So string functions with the user provided data becomes the new data type in ‘C’.
Fig. 4.1 : String data type
To use the functions related to strings, user only need to include ‘string.h’ header file. All the definitions details of these functions are keep hidden from the user, user can directly use these function without knowing all the implementation details. This is known as abstraction or hiding.
String Manipulation in C Language
Strings are also called as the array of character.
- A special character usually known as null character (\0) is used to indicate the end of the string.
- To read and write the string in C program %s access specifier is required.
- C language provides several built in functions for the manipulation of the string
- To use the built in functions for string, user need to include string.h header file.
- Syntax for declaring string is
One dimensional Array
A one-dimensional array is a group of elements having the same datatype and same name. Individual elements are referred to using common name and unique index of the elements.
The simplest form of an array is one-dimensional-array. The array itself is given name and its elements are referred to by their subscripts. In , an array is denoted as follows:
Array_name[array_size]
Where size specifies the number of elements in the array and the subscript (also called index) value ranges from 0 through size-1.
Declare One Dimensional Array
Here is the general form to declare one dimensional array in
Data_typearray_name[array_size];
Here, data_type is any valid data type, array_name is the name of the array, and array_size is the size of array. Here is an example, declaring an array named arr of int type, having maximum element size of 10 elements
Intarr[10];
Initialize One Dimensional Array
Here is the general form to initialize values to one dimensional array
Data_typearray_name[array_size] = {comma_separated_element_list};
Here is an example, declaring and initializing values to the array name arr of type int, containing 10 elements
Intarr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
One Dimensional Array Example
Here are some example program, demonstrating one dimensional array
/*One Dimensional Array */
#include<iostream.h>
#include<conio.h>
Void main()
{
Clrscr();
Intarr[5] = {1, 2, 3, 4, 5};
Inti;
For(i=0; i<5; i++)
{
Cout<<"arr["<<i<<"] = "<<arr[i]<<"\n";
}
Getch();
}
Here is the sample output of this program:
Here is another example, also demonstrating one dimension array in
/* One Dimensional Array */
#include<iostream.h>
#include<conio.h>
Void main()
{
Clrscr();
Intarr[10];
Inti;
Int sum=0, avg=0;
Cout<<"Enter 10 array elements: ";
For(i=0; i<10; i++)
{
Cin>>arr[i];
Sum = sum + arr[i];
}
Cout<<"\nThe array elements are: \n";
For(i=0; i<10; i++)
{
Cout<<arr[i]<<" ";
}
Cout<<"\n\nSum of all elements is: "<<sum;
Avg = sum/10;
Cout<<"\nAnd average is: "<<avg;
Getch();
}
Here is the sample run of the above program:
Below is another program on one-dimensional array in
/* One Dimensional Array */
#include<iostream.h>
#include<conio.h>
Void main()
{
Clrscr();
Intarr[5];
Inti, position, index;
Cout<<"Enter 5 array elements: ";
For(i=0; i<5; i++)
{
Cin>>arr[i];
}
Cout<<"\nIndex\t\tPosition";
For(i=0; i<5; i++)
{
Cout<<"\n";
Cout<<i<<" = "<<arr[i]<<"\t\t"<<i+1<<" = "<<arr[i+1];
}
Cout<<" (Garbage value/not of array)";
Cout<<"\n\nImportant - Array element can only be accessed by indexing the array\n";
Cout<<"Note - Array index always starts from 0";
Getch();
}
Below is the sample run of this program:
Let's take one more program, on single or one dimensional array
/* One Dimensional Array */
#include<iostream.h>
#include<conio.h>
Void main()
{
Clrscr();
Intarr[10];
Inti, position, index;
Cout<<"Enter 10 array elements: ";
For(i=0; i<10; i++)
{
Cin>>arr[i];
}
Cout<<"Accessing element at position...Enter position...";
Cin>>position;
Cout<<"\nElement present at position "<<position<<" is "<<arr[position+1];
Cout<<"\n\nAccessing element at index..Enter index..";
Cin>>index;
Cout<<"\nElement present at index "<<index<<" is "<<arr[index];
Getch();
}
Here is the sample run of the above program:
Multidimensional Array
Two Dimensional Array in C
The two-dimensional array can be defined as an array of arrays. The 2D array is organized as matrices which can be represented as the collection of rows and columns. However, 2D arrays are created to implement a relational database lookalike data structure. It provides ease of holding the bulk of data at once which can be passed to any number of functions wherever required.
Declaration of two dimensional Array in C
The syntax to declare the 2D array is given below.
- Data_type array_name[rows][columns];
Consider the following example.
- Int twodimen[4][3];
Here, 4 is the number of rows, and 3 is the number of columns.
Initialization of 2D Array in C
In the 1D array, we don't need to specify the size of the array if the declaration and initialization are being done simultaneously. However, this will not work with 2D arrays. We will have to define at least the second dimension of the array. The two-dimensional array can be declared and defined in the following way.
- Int arr[4][3]={{1,2,3},{2,3,4},{3,4,5},{4,5,6}};
Two-dimensional array example in C
- #include<stdio.h>
- Int main(){
- Int i=0,j=0;
- Int arr[4][3]={{1,2,3},{2,3,4},{3,4,5},{4,5,6}};
- //traversing 2D array
- For(i=0;i<4;i++){
- For(j=0;j<3;j++){
- Printf("arr[%d] [%d] = %d \n",i,j,arr[i][j]);
- }//end of j
- }//end of i
- Return 0;
- }
Output
Arr[0][0] = 1
Arr[0][1] = 2
Arr[0][2] = 3
Arr[1][0] = 2
Arr[1][1] = 3
Arr[1][2] = 4
Arr[2][0] = 3
Arr[2][1] = 4
Arr[2][2] = 5
Arr[3][0] = 4
Arr[3][1] = 5
Arr[3][2] = 6
C 2D array example: Storing elements in a matrix and printing it.
- #include <stdio.h>
- Void main ()
- {
- Int arr[3][3],i,j;
- For (i=0;i<3;i++)
- {
- For (j=0;j<3;j++)
- {
- Printf("Enter a[%d][%d]: ",i,j);
- Scanf("%d",&arr[i][j]);
- }
- }
- Printf("\n printing the elements ....\n");
- For(i=0;i<3;i++)
- {
- Printf("\n");
- For (j=0;j<3;j++)
- {
- Printf("%d\t",arr[i][j]);
- }
- }
- }
Output
Enter a[0][0]: 56
Enter a[0][1]: 10
Enter a[0][2]: 30
Enter a[1][0]: 34
Enter a[1][1]: 21
Enter a[1][2]: 34
Enter a[2][0]: 45
Enter a[2][1]: 56
Enter a[2][2]: 78
Printing the elements ....
56 10 30
34 21 34
45 56 78
Strings are actually one-dimensional array of characters terminated by a null character '\0'. Thus a null-terminated string contains the characters that comprise the string followed by a null.
The following declaration and initialization create a string consisting of the word "Hello". To hold the null character at the end of the array, the size of the character array containing the string is one more than the number of characters in the word "Hello."
Char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
If you follow the rule of array initialization then you can write the above statement as follows −
Char greeting[] = "Hello";
Following is the memory presentation of the above defined string in C/C++ −
Actually, you do not place the null character at the end of a string constant. The C compiler automatically places the '\0' at the end of the string when it initializes the array. Let us try to print the above mentioned string −
#include <stdio.h>
Int main () {
Char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
Printf("Greeting message: %s\n", greeting );
Return 0;
}
When the above code is compiled and executed, it produces the following result −
Greeting message: Hello
C supports a wide range of functions that manipulate null-terminated strings −
Sr.No. | Function & Purpose |
1 | Strcpy(s1, s2); Copies string s2 into string s1. |
2 | Strcat(s1, s2); Concatenates string s2 onto the end of string s1. |
3 | Strlen(s1); Returns the length of string s1. |
4 | Strcmp(s1, s2); Returns 0 if s1 and s2 are the same; less than 0 if s1<s2; greater than 0 if s1>s2. |
5 | Strchr(s1, ch); Returns a pointer to the first occurrence of character ch in string s1. |
6 | Strstr(s1, s2); Returns a pointer to the first occurrence of string s2 in string s1. |
The following example uses some of the above-mentioned functions –
#include <stdio.h>
#include <string.h>
Int main () {
Char str1[12] = "Hello";
Char str2[12] = "World";
Char str3[12];
Intlen ;
/* copy str1 into str3 */
Strcpy(str3, str1);
Printf("strcpy( str3, str1) : %s\n", str3 );
/* concatenates str1 and str2 */
Strcat( str1, str2);
Printf("strcat( str1, str2): %s\n", str1 );
/* total lenghth of str1 after concatenation */
Len = strlen(str1);
Printf("strlen(str1) : %d\n", len );
Return 0;
}
When the above code is compiled and executed, it produces the following result −
Strcpy( str3, str1) : Hello
Strcat( str1, str2): HelloWorld
Strlen(str1) : 10
How to Declare and Initialize a String in C
A C String is a simple array with char as a data type. 'C' language does not directly support string as a data type. Hence, to display a String in C, you need to make use of a character array.
The general syntax for declaring a variable as a String in C is as follows,
Charstring_variable_name [array_size];
The classic Declaration of strings can be done as follow:
Charstring_name[string_length] = "string";
The size of an array must be defined while declaring a C String variable because it is used to calculate how many characters are going to be stored inside the string variable in C. Some valid examples of string declaration are as follows,
Charfirst_name[15]; //declaration of a string variable
Charlast_name[15];
The above example represents string variables with an array size of 15. This means that the given C string array is capable of holding 15 characters at most. The indexing of array begins from 0 hence it will store characters from a 0-14 position. The C compiler automatically adds a NULL character '\0' to the character array created.
Let's study the String initialization in C. Following example demonstrates the initialization of Strings in C,
Charfirst_name[15] = "ANTHONY";
Charfirst_name[15] = {'A','N','T','H','O','N','Y','\0'}; // NULL character '\0' is required at end in this declaration
Char string1 [6] = "hello";/* string size = 'h'+'e'+'l'+'l'+'o'+"NULL" = 6 */
Char string2 [ ] = "world"; /* string size = 'w'+'o'+'r'+'l'+'d'+"NULL" = 6 */
Char string3[6] = {'h', 'e', 'l', 'l', 'o', '\0'} ; /*Declaration as set of characters ,Size 6*/
In string3, the NULL character must be added explicitly, and the characters are enclosed in single quotation marks.
'C' also allows us to initialize a string variable without defining the size of the character array. It can be done in the following way,
Charfirst_name[ ] = "NATHAN";
The name of Strings in C acts as a pointer because it is basically an array.
When we say Input, it means to feed some data into a program. An input can be given in the form of a file or from the command line. C programming provides a set of built-in functions to read the given input and feed it to the program as per requirement.
When we say Output, it means to display some data on screen, printer, or in any file. C programming provides a set of built-in functions to output the data on the computer screen as well as to save it in text or binary files.
The Standard Files
C programming treats all the devices as files. So devices such as the display are addressed in the same way as files and the following three files are automatically opened when a program executes to provide access to the keyboard and screen.
Standard File | File Pointer | Device |
Standard input | Stdin | Keyboard |
Standard output | Stdout | Screen |
Standard error | Stderr | Your screen |
The file pointers are the means to access the file for reading and writing purpose. This section explains how to read values from the screen and how to print the result on the screen.
The getchar() and putchar() Functions
The intgetchar(void) function reads the next available character from the screen and returns it as an integer. This function reads only single character at a time. You can use this method in the loop in case you want to read more than one character from the screen.
The intputchar(int c) function puts the passed character on the screen and returns the same character. This function puts only single character at a time. You can use this method in the loop in case you want to display more than one character on the screen. Check the following example −
#include<stdio.h>
Int main(){
Int c;
Printf("Enter a value :");
c =getchar();
Printf("\nYou entered: ");
Putchar( c );
Return0;
}
When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then the program proceeds and reads only a single character and displays it as follows −
$./a.out
Enter a value : this is test
You entered: t
The gets() and puts() Functions
The char *gets(char *s) function reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF (End of File).
The intputs(const char *s) function writes the string 's' and 'a' trailing newline to stdout.
NOTE: Though it has been deprecated to use gets() function, Instead of using gets, you want to use fgets().
#include<stdio.h>
Int main(){
Charstr[100];
Printf("Enter a value :");
Gets(str);
Printf("\nYou entered: ");
Puts(str);
Return0;
}
When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then the program proceeds and reads the complete line till end, and displays it as follows −
$./a.out
Enter a value : this is test
You entered: this is test
The scanf() and printf() Functions
The intscanf(const char *format, ...) function reads the input from the standard input stream stdin and scans that input according to the format provided.
The intprintf(const char *format, ...) function writes the output to the standard output stream stdout and produces the output according to the format provided.
The format can be a simple constant string, but you can specify %s, %d, %c, %f, etc., to print or read strings, integer, character or float respectively. There are many other formatting options available which can be used based on requirements. Let us now proceed with a simple example to understand the concepts better −
#include<stdio.h>
Int main(){
Charstr[100];
Inti;
Printf("Enter a value :");
Scanf("%s %d",str,&i);
Printf("\nYou entered: %s %d ",str,i);
Return0;
}
When the above code is compiled and executed, it waits for you to input some text. When you enter a text and press enter, then program proceeds and reads the input and displays it as follows −
$./a.out
Enter a value : seven 7
You entered: seven 7
Here, it should be noted that scanf() expects input in the same format as you provided %s and %d, which means you have to provide valid inputs like "string integer". If you provide "string string" or "integer integer", then it will be assumed as wrong input. Secondly, while reading a string, scanf() stops reading as soon as it encounters a space, so "this is test" are three strings for scanf().
1) strlen( ) Function :
Strlen( ) function is used to find the length of a character string.
Example: int n;
Charst[20] = “Bangalore”;
n = strlen(st);
• This will return the length of the string 9 which is assigned to an integer variable n.
• Note that the null character “\0‟ available at the end of a string is not counted.
2) strcpy( ) Function :
Strcpy( ) function copies contents of one string into another string. Syntax for strcpy function is given below.
Syntax: char * strcpy (char * destination, const char * source);
Example:
Strcpy ( str1, str2) – It copies contents of str2 into str1.
Strcpy ( str2, str1) – It copies contents of str1 into str2.
If destination string length is less than source string, entire source string value won’t be copied into destination string.
For example, consider destination string length is 20 and source string length is 30. Then, only 20 characters from source string will be copied into destination string and remaining 10 characters won’t be copied and will be truncated.
Example : char city[15];
Strcpy(city, “BANGALORE”) ;
This will assign the string “BANGALORE” to the character variable city.
3) strcat( ) Function :
Strcat( ) function in C language concatenates two given strings. It concatenates source string at the end of destination string. Syntax for strcat( ) function is given below.
Syntax : char * strcat ( char * destination, const char * source );
Example :
Strcat ( str2, str1 ); - str1 is concatenated at the end of str2.
Strcat ( str1, str2 ); - str2 is concatenated at the end of str1.
• As you know, each string in C is ended up with null character (‘\0′).
• In strcat( ) operation, null character of destination string is overwritten by source string’s first character and null character is added at the end of new destination string which is created afterstrcat( ) operation.
Program : The following program is an example of strcat() function
#include <stdio.h>
#include <string.h>
Intmain()
{
Char source[]= “ ftl” ;
Char target[]= “ welcome to” ;
Printf(“\n Source string =%s”, source );
Printf( “\n Target string =%s”, target );
Strcat( target, source );
Printf( “\n Target string after strcat()=%s”, target );
}
Output :
Source string = ftl
Target string = welcome to
Target string after strcat() = welcome to ftl
4) Strncat() function :
Strncat( ) function in C language concatenates (appends) portion of one string at the end of another string.
Syntax : char * strncat ( char * destination, const char * source, size_tnum );
Example :
strncat ( str2, str1, 3 ); – First 3 characters of str1 is concatenated at the end of str2.
strncat ( str1, str2, 3 ); - First 3 characters of str2 is concatenated at the end of str1.
As you know, each string in C is ended up with null character (‘\0′).
In strncat( ) operation, null character of destination string is overwritten by source string’s first character and null character is added at the end of new destination string which is created after strncat( ) operation.
Program : The following program is an example of strncat() function
#include <stdio.h>
#include <string.h>
Intma in()
{
Charsource[]=”" ftl” ;
Char target[]= “welcome to” ;
Printf( “\n Source string =%s”, source );
Printf( “\n Target string =%s”, target );
Strncat( target, source,3);
Printf( "”\n Target string after strncat()=%s”, target );
}
Output :
Source string = ftl
Target string = welcome to
Target string after strncat()= welcome to ft
5) strcmp( ) Function :
Strcmp( ) function in C compares two given strings and returns zero if they are same. If length of string1 < string2, it returns < 0 value. If length of string1 > string2, it returns > 0 value.
Syntax :intstrcmp ( const char * str1, const char * str2 );
Strcmp( ) function is case sensitive. i.e., “A” and “a” are treated as different characters.
Example :
char city[20] = “Madras”;
char town[20] = “Mangalore”;
strcmp(city, town);
This will return an integer value “-10‟ which is the difference in the ASCII values of the first mismatching letters “D‟ and “N‟.
* Note that the integer value obtained as the difference may be assigned to an integer variable as follows:
Int n;
n = strcmp(city, town);
6) strcmpi() function :
Strcmpi( ) function in C is same as strcmp() function. But, strcmpi( ) function is not case sensitive. i.e., “A” and “a” are treated as same characters. Whereas, strcmp() function treats “A” and “a” as different characters.
• strcmpi() function is non standard function which may not available in standard library.
• Both functions compare two given strings and returns zero if they are same.
• If length of string1 < string2, it returns < 0 value. If length of string1 > string2, it returns > 0 value.
Strcmp( ) function is case sensitive. i.e., “A” and “a” are treated as different characters.
Syntax :intstrcmpi ( const char * str1, const char * str2 );
Example :
m=strcmpi(“ DELHI ”, “ delhi ”); m = 0.
7) strlwr() function :
Strlwr() function converts a given string into lowercase.
Syntax : char *strlwr(char *string);
Strlwr() function is non standard function which may not available in standard library in C.
Program : In this program, string ”MODIFY This String To LOwer” is converted into lower case using strlwr( ) function and result is displayed as “modify this string to lower”.
#include<stdio.h>
#include<string.h>
Intmain()
{
Charstr[]= “MODIFY This String To Lower”;
Printf(“%s\n”,strlwr(str));
Return0;
}
Output :
Modify this string to lower
8) strupr() function :
Strupr() function converts a given string into uppercase.
Syntax : char *strupr(char *string);
Strupr() function is non standard function which may not available in standard library in C.
Program : In this program, string ”Modify This String To Upper” is converted into uppercase using strupr( ) function and result is displayed as “MODIFY THIS STRING TO UPPER”.
#include<stdio.h>
#include<string.h>
Intmain()
{
Charstr[]= “Modify This String To Upper”;
Printf(“%s\n”,strupr(str));
Return0;
}
Output :
MODIFY THIS STRING TO UPPER
9) strrev() function :
Strrev() function reverses a given string in C language.
Syntax : char *strrev(char *string);
Strrev() function is non standard function which may not available in standard library in C.
Example :
char name[20]=”ftl”; then
strrev(name)= ltf
Program : In below program, string “Hello” is reversed using strrev( ) function and output is displayed as “olleH”.
#include<stdio.h>
#include<string.h>
Intmain()
{
Char name[30]= “Hello”;
Printf(“String before strrev():%s\n”, name);
Printf(“String after strrev():%s”,strrev(name));
Return0;
}
Output :
String before strrev( ) : Hello
String after strrev( ) : olleH
10) strchr() function :
Strchr() function returns pointer to the first occurrence of the character in a given string.
Syntax : char *strchr(const char *str, int character);
Program : In this program, strchr( ) function is used to locate first occurrence of the character ‘i’ in the string ”This is a string ”. Character ‘i’ is located at position 3 and pointer is returned at first occurrence of the character ‘i’.
#include <stdio.h>
#include <string.h>
Intmain()
{
Char string[25]=”This is a string “;
Char*p;
p =strchr(string,'i');
Printf(“Character i is found at position %d\n”,p-string+1);
Printf(“First occurrence of character \”i\” in \”%s\” is” \” \”%s\””,string, p);
Return0;
}
Output :
Character i is found at position 3
First occurrence of character “i” in “This is a string” is “is is a string”
11) strstr() function :
Strstr( ) function returns pointer to the first occurrence of the string in a given string.
Syntax : char *strstr(const char *str1, const char *str2);
Program : In this program, strstr( ) function is used to locate first occurrence of the string “test” in the string ”This is a test string for testing”. Pointer is returned at first occurrence of the string “test”.
#include <stdio.h>
#include <string.h>
Intmain()
{
Charstring[55]=”This is a test string for testing”;
Char*p;
p =strstr(string, ”test”);
If(p)
{
Printf(“string found\n” );
Printf(“First occurrence of string \”test\” in \”%s\” is”\” \”%s\””,string, p);
}
Elseprintf(“string not found\n” );
Return0;
}
Output :
String found
First occurrence of ”test” in “this is a test string for testing” is “testing string for testing”
12) atoi() function :
It converts string-value to numeric-value and it converts a numeric-string value to equivalent integer-value.
Syntax :intatoi(string);
Example :
printf(“output=%d”, atoi(“123”)+atoi(“234”));
This printf() will print 357
13) atol() function :
Converts a long int string value to equivalent long integer value.
Syntax : long intatol(string);
Example :
printf(“output=%d”, atol(“486384”)-atol(“112233”));
This statement will print 374151
14) atof() function :
Converts a floating point text format value to double value.
Syntax :intatoi(string);
Example :
printf(“%1f”,atof(“3.1412”)*5*5);
This statement will print 78.530000
15) itoa(),ltoa(),ultoa() :
These functions converts a given number(int/long int/unsigned long int) to equivalent text format based on the given numbering system radix value.
These functions take three arguments, the numeric value, target string address in which the value to be stored and radix value. Finally returns the target string address, so that function-call can be used as argument/expression.
Syntax : char* itoa(int value, char *targetstringaddress, int radix );
Example :
Char temp[50];
Printf(“output=%s”, itoa(45,temp,2));
Output : 101101
Program : Write a C program to count the number of vowels present in a sentence.
# include<stdio.h>
# include<conio.h>
# include<string.h>
Main()
{
Charst[80],ch;
Int count=0,i;
Clrscr();
Printf(“ \n Enter the sentence: \n”);
Gets(st);
For(i=0;i<strlen(st);i++)
Switch(st[i])
{
Case ‘A’:
Case ‘E’:
Case ‘I’:
Case ‘O’:
Case ‘U’:
Case ‘a’:
Case ‘e’:
Case ‘I’:
Case ‘o’:
Case ‘u’:
Count++;
Break;
}
Printf(“\n %d vowels are present in the sentence”, count);
Getch();
}
• When this program is executed, the user has to enter the sentence.
• Note that gets( ) function is used to read the sentence because the string has white spaces between the words.
• The vowels are counted using a switch statement in a loop.
• Note that a count++ statement is given only once to execute it for the cases in the switch statement.
Output :
Enter the sentence :
This is a book
5 vowels are present in the sentence.
Program : Write a C program to count no of lines, words and characters in a given text.
# include<stdio.h>
# include<string.h>
# include<conio.h>
Main()
{
Char txt[250],ch,st[30];
Int ins,wds,chs,i;
Printf(“ \n Enter the text, type $ st end \n \n”);
i=0;
While((txt[i++]=getchar())!=’$’);
i--;
St[i]= ‘\0’;
Ins=wds=chs=0;
i=0;
While(txt[i]!=’$’)
{
Switch(txt[i])
{
Case ‘,’:
Case ‘!’:
Case ‘\t’:
Case ‘ ‘:
{
Wds++;
Chs++;
Break;
}
Case ‘?’:
Case ‘.’:
{
Wds++;
Chs++;
Break;
}
Default:chs++;
Break;
}
i++;
}
Printf(“\n\n no of char(incl.blanks)=%d”,chs);
Printf(“\n No. of words =%d”,wds);
Printf(“\n No of lines =%d”, ins);
Getch();
}
Output :
Enter the text, type $ at end
What is a string? How do you initialize it? Explain with example.
With example: $
No of char: (inch. Blanks) = 63
No of words = 12
No of lines =1.
There are a number of good ways to do this. The following suggestion is only one of them. However, it is relatively easy to implement and understand. It uses 3 concepts that you must introduce into your program.
- Use an array of pointers to the message strings.
- Use a list of manifest constants to index into the pointer array.
- Use a single macro to access any string.
The first step is to create an assembly file (a very simple one) that contains the messages and a table of pointers to the messages. Since you will probably want to locate the table at a fixed address, this is best way to do that. For example:
;The following is an array of pointers to the messages
Cseg at 08000 ; *** Change this for your assembler ***
Hstrtab: dw str1
Dw str2
Dw str3
Dw str4
; Here are the messages
Str1: db 'Bon Jour', 0
Str2: db 'Adios', 0
Str3: db 'Merci', 0
Str4: db 'Please', 0
End
Next, create a manifest constant (using #define or enum) for each message in the table. You will use these to index into the array. For example:
Enummessage_strings
{
MSG_HELLO = 0,
MSG_GOODBYE,
MSG_THANKS,
MSG_PLEASE
};
Finally, you need a macro that lets you reference strtab in your C program:
#define MSGTAB ((char code * code *) 0x8000)
The only trick here is that the addresses (0x8000 in the C program and 8000h in the assembly file) must match.
Now, you are ready to access the strings in your C program.
Void main (void)
{
SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 221; /* TH1: reload value for 1200 baud @ 16MHz */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */
Printf ("%s\n", MSGTAB [MSG_HELLO]);
Printf ("%s\n", MSGTAB [MSG_GOODBYE]);
Printf ("%s\n", MSGTAB [MSG_THANKS]);
Printf ("%s\n", MSGTAB [MSG_PLEASE]);
}
A matrix is a two-dimensional data object made of m rows and n columns, therefore having total m x n values. If most of the elements of the matrix have 0 value, then it is called a sparse matrix.
Why to use Sparse Matrix instead of simple matrix ?
- Storage: There are lesser non-zero elements than zeros and thus lesser memory can be used to store only those elements.
- Computing time: Computing time can be saved by logically designing a data structure traversing only non-zero elements..
Example:
0 0 3 0 4
0 0 5 7 0
0 0 0 0 0
0 2 6 0 0
Representing a sparse matrix by a 2D array leads to wastage of lots of memory as zeroes in the matrix are of no use in most of the cases. So, instead of storing zeroes with non-zero elements, we only store non-zero elements. This means storing non-zero elements with triples- (Row, Column, value).
Sparse Matrix Representations can be done in many ways following are two common representations:
- Array representation
- Linked list representation
Method 1: Using Arrays
2D array is used to represent a sparse matrix in which there are three rows named as
- Row: Index of row, where non-zero element is located
- Column: Index of column, where non-zero element is located
- Value: Value of the non zero element located at index – (row,column)
// C++ program for Sparse Matrix Representation // using Array #include<stdio.h>
Intmain() { // Assume 4x5 sparse matrix IntsparseMatrix[4][5] = { {0 , 0 , 3 , 0 , 4 }, {0 , 0 , 5 , 7 , 0 }, {0 , 0 , 0 , 0 , 0 }, {0 , 2 , 6 , 0 , 0 } };
Intsize = 0; For(inti = 0; i< 4; i++) For(intj = 0; j < 5; j++) If(sparseMatrix[i][j] != 0) Size++;
// number of columns in compactMatrix (size) must be // equal to number of non - zero elements in // sparseMatrix IntcompactMatrix[3][size];
// Making of new matrix Intk = 0; For(inti = 0; i< 4; i++) For(intj = 0; j < 5; j++) If(sparseMatrix[i][j] != 0) { CompactMatrix[0][k] = i; CompactMatrix[1][k] = j; CompactMatrix[2][k] = sparseMatrix[i][j]; k++; }
For(inti=0; i<3; i++) { For(intj=0; j<size; j++) Printf("%d ", compactMatrix[i][j]);
Printf("\n"); } Return0; } |
Output:
0 0 1 1 3 3
2 4 2 3 1 2
3 4 5 7 2 6
Method 2: Using Linked Lists
In linked list, each node has four fields. These four fields are defined as:
- Row: Index of row, where non-zero element is located
- Column: Index of column, where non-zero element is located
- Value: Value of the non zero element located at index – (row,column)
- Next node: Address of the next node
// C program for Sparse Matrix Representation // using Linked Lists #include<stdio.h> #include<stdlib.h>
// Node to represent sparse matrix StructNode { Intvalue; Introw_position; Intcolumn_postion; StructNode *next; };
// Function to create new node Voidcreate_new_node(structNode** start, intnon_zero_element, Introw_index, intcolumn_index ) { StructNode *temp, *r; Temp = *start; If(temp == NULL) { // Create new node dynamically Temp = (structNode *) malloc(sizeof(structNode)); Temp->value = non_zero_element; Temp->row_position = row_index; Temp->column_postion = column_index; Temp->next = NULL; *start = temp;
} Else { While(temp->next != NULL) Temp = temp->next;
// Create new node dynamically r = (structNode *) malloc(sizeof(structNode)); r->value = non_zero_element; r->row_position = row_index; r->column_postion = column_index; r->next = NULL; Temp->next = r;
} }
// This function prints contents of linked list // starting from start VoidPrintList(structNode* start) { StructNode *temp, *r, *s; Temp = r = s = start;
Printf("row_position: "); While(temp != NULL) {
Printf("%d ", temp->row_position); Temp = temp->next; } Printf("\n");
Printf("column_postion: "); While(r != NULL) { Printf("%d ", r->column_postion); r = r->next; } Printf("\n"); Printf("Value: "); While(s != NULL) { Printf("%d ", s->value); s = s->next; } Printf("\n"); }
// Driver of the program Intmain() { // Assume 4x5 sparse matrix IntsparseMatric[4][5] = { {0 , 0 , 3 , 0 , 4 }, {0 , 0 , 5 , 7 , 0 }, {0 , 0 , 0 , 0 , 0 }, {0 , 2 , 6 , 0 , 0 } };
/* Start with the empty list */ StructNode* start = NULL;
For(inti = 0; i< 4; i++) For(intj = 0; j < 5; j++)
// Pass only those values which are non - zero If(sparseMatric[i][j] != 0) Create_new_node(&start, sparseMatric[i][j], i, j);
PrintList(start);
Return0; } |
Output:
Row_position: 0 0 1 1 3 3
Column_postion: 2 4 2 3 1 2
Value: 3 4 5 7 2 6
Storage Classes in C
Storage classes in C are used to determine the lifetime, visibility, memory location, and initial value of a variable. There are four types of storage classes in C
- Automatic
- External
- Static
- Register
Storage Classes | Storage Place | Default Value | Scope | Lifetime |
Auto | RAM | Garbage Value | Local | Within function |
Extern | RAM | Zero | Global | Till the end of the main program Maybe declared anywhere in the program |
Static | RAM | Zero | Local | Till the end of the main program, Retains value between multiple functions call |
Register | Register | Garbage Value | Local | Within the function |
Automatic
- Automatic variables are allocated memory automatically at runtime.
- The visibility of the automatic variables is limited to the block in which they are defined.
The scope of the automatic variables is limited to the block in which they are defined.
- The automatic variables are initialized to garbage by default.
- The memory assigned to automatic variables gets freed upon exiting from the block.
- The keyword used for defining automatic variables is auto.
- Every local variable is automatic in C by default.
Example 1
- #include <stdio.h>
- Int main()
- {
- Int a; //auto
- Char b;
- Float c;
- Printf("%d %c %f",a,b,c); // printing initial default value of automatic variables a, b, and c.
- Return 0;
- }
Output:
Garbagegarbagegarbage
Example 2
- #include <stdio.h>
- Int main()
- {
- Int a = 10,i;
- Printf("%d ",++a);
- {
- Int a = 20;
- For (i=0;i<3;i++)
- {
- Printf("%d ",a); // 20 will be printed 3 times since it is the local value of a
- }
- }
- Printf("%d ",a); // 11 will be printed since the scope of a = 20 is ended.
- }
Output:
11 20 20 20 11
Static
- The variables defined as static specifier can hold their value between the multiple function calls.
- Static local variables are visible only to the function or the block in which they are defined.
- A same static variable can be declared many times but can be assigned at only one time.
- Default initial value of the static integral variable is 0 otherwise null.
- The visibility of the static global variable is limited to the file in which it has declared.
- The keyword used to define static variable is static.
Example 1
- #include<stdio.h>
- Static char c;
- Static int i;
- Static float f;
- Static char s[100];
- Void main ()
- {
- Printf("%d %d %f %s",c,i,f); // the initial default value of c, i, and f will be printed.
- }
Output:
0 0 0.000000 (null)
Example 2
- #include<stdio.h>
- Void sum()
- {
- Static int a = 10;
- Static int b = 24;
- Printf("%d %d \n",a,b);
- a++;
- b++;
- }
- Void main()
- {
- Int i;
- For(i = 0; i< 3; i++)
- {
- Sum(); // The static variables holds their value between multiple function calls.
- }
- }
Output:
10 24
11 25
12 26
Register
- The variables defined as the register is allocated the memory into the CPU registers depending upon the size of the memory remaining in the CPU.
- We can not dereference the register variables, i.e., we can not use &operator for the register variable.
- The access time of the register variables is faster than the automatic variables.
- The initial default value of the register local variables is 0.
- The register keyword is used for the variable which should be stored in the CPU register. However, it is compiler?s choice whether or not; the variables can be stored in the register.
- We can store pointers into the register, i.e., a register can store the address of a variable.
- Static variables can not be stored into the register since we can not use more than one storage specifier for the same variable.
Example 1
- #include <stdio.h>
- Int main()
- {
- Register int a; // variable a is allocated memory in the CPU register. The initial default value of a is 0.
- Printf("%d",a);
- }
Output:
0
Example 2
- #include <stdio.h>
- Int main()
- {
- Register int a = 0;
- Printf("%u",&a); // This will give a compile time error since we can not access the address of a register variable.
- }
Output:
Main.c:5:5: error: address of register variable ?a? requested
Printf("%u",&a);
^~~~~~
External
- The external storage class is used to tell the compiler that the variable defined as extern is declared with an external linkage elsewhere in the program.
- The variables declared as extern are not allocated any memory. It is only declaration and intended to specify that the variable is declared elsewhere in the program.
- The default initial value of external integral type is 0 otherwise null.
- We can only initialize the extern variable globally, i.e., we can not initialize the external variable within any block or method.
- An external variable can be declared many times but can be initialized at only once.
- If a variable is declared as external then the compiler searches for that variable to be initialized somewhere in the program which may be extern or static. If it is not, then the compiler will show an error.
Example 1
- #include <stdio.h>
- Int main()
- {
- Extern int a;
- Printf("%d",a);
- }
Output
Main.c:(.text+0x6): undefined reference to a'
Collect2: error: ld returned 1 exit status
Example 2
- #include <stdio.h>
- Int a;
- Int main()
- {
- Extern int a; // variable a is defined globally, the memory will not be allocated to a
- Printf("%d",a);
- }
Output
0
Example 3
- #include <stdio.h>
- Int a;
- Int main()
- {
- Extern int a = 0; // this will show a compiler error since we can not use extern and initializer at same time
- Printf("%d",a);
- }
Output
Compile time error
Main.c: In function ?main?:
Main.c:5:16: error: ?a? has both ?extern? and initializer
Externint a = 0;
Example 4
- #include <stdio.h>
- Int main()
- {
- Extern int a; // Compiler will search here for a variable a defined and initialized somewhere in the pogram or not.
- Printf("%d",a);
- }
- Int a = 20;
Output
20
Example 5
- Extern int a;
- Int a = 10;
- #include <stdio.h>
- Int main()
- {
- Printf("%d",a);
- }
- Int a = 20; // compiler will show an error at this line
Output
Compile time error
C - Preprocessors
The C Preprocessor is not a part of the compiler, but is a separate step in the compilation process. In simple terms, a C Preprocessor is just a text substitution tool and it instructs the compiler to do required pre-processing before the actual compilation. We'll refer to the C Preprocessor as CPP.
All preprocessor commands begin with a hash symbol (#). It must be the first nonblank character, and for readability, a preprocessor directive should begin in the first column. The following section lists down all the important preprocessor directives −
Sr.No. | Directive & Description |
1 | #define Substitutes a preprocessor macro. |
2 | #include Inserts a particular header from another file. |
3 | #undef Undefines a preprocessor macro. |
4 | #ifdef Returns true if this macro is defined. |
5 | #ifndef Returns true if this macro is not defined. |
6 | #if Tests if a compile time condition is true. |
7 | #else The alternative for #if. |
8 | #elif #else and #if in one statement. |
9 | #endif Ends preprocessor conditional. |
10 | #error Prints error message on stderr. |
11 | #pragma Issues special commands to the compiler, using a standardized method. |
Preprocessors Examples
Analyze the following examples to understand various directives.
#define MAX_ARRAY_LENGTH 20
This directive tells the CPP to replace instances of MAX_ARRAY_LENGTH with 20. Use #define for constants to increase readability.
#include<stdio.h>
#include"myheader.h"
These directives tell the CPP to get stdio.h from System Libraries and add the text to the current source file. The next line tells CPP to get myheader.h from the local directory and add the content to the current source file.
#undef FILE_SIZE
#define FILE_SIZE 42
It tells the CPP to undefine existing FILE_SIZE and define it as 42.
#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif
It tells the CPP to define MESSAGE only if MESSAGE isn't already defined.
#ifdef DEBUG
/* Your debugging statements here */
#endif
It tells the CPP to process the statements enclosed if DEBUG is defined. This is useful if you pass the -DDEBUG flag to the gcc compiler at the time of compilation. This will define DEBUG, so you can turn debugging on and off on the fly during compilation.
Predefined Macros
ANSI C defines a number of macros. Although each one is available for use in programming, the predefined macros should not be directly modified.
Sr.No. | Macro & Description |
1 | __DATE__ The current date as a character literal in "MMM DD YYYY" format. |
2 | __TIME__ The current time as a character literal in "HH:MM:SS" format. |
3 | __FILE__ This contains the current filename as a string literal. |
4 | __LINE__ This contains the current line number as a decimal constant. |
5 | __STDC__ Defined as 1 when the compiler complies with the ANSI standard. |
Let's try the following example −
#include<stdio.h>
Int main(){
Printf("File :%s\n", __FILE__ );
Printf("Date :%s\n", __DATE__ );
Printf("Time :%s\n", __TIME__ );
Printf("Line :%d\n", __LINE__ );
Printf("ANSI :%d\n", __STDC__ );
}
When the above code in a file test.c is compiled and executed, it produces the following result −
File :test.c
Date :Jun 2 2012
Time :03:36:24
Line :8
ANSI :1
Preprocessor Operators
The C preprocessor offers the following operators to help create macros −
The Macro Continuation (\) Operator
A macro is normally confined to a single line. The macro continuation operator (\) is used to continue a macro that is too long for a single line. For example −
#definemessage_for(a, b) \
Printf(#a " and "#b ": We love you!\n")
The Stringize (#) Operator
The stringize or number-sign operator ( '#' ), when used within a macro definition, converts a macro parameter into a string constant. This operator may be used only in a macro having a specified argument or parameter list. For example −
#include<stdio.h>
#definemessage_for(a, b) \
Printf(#a " and "#b ": We love you!\n")
Int main(void){
Message_for(Carole,Debra);
Return0;
}
When the above code is compiled and executed, it produces the following result −
Carole and Debra: We love you!
The Token Pasting (##) Operator
The token-pasting operator (##) within a macro definition combines two arguments. It permits two separate tokens in the macro definition to be joined into a single token. For example −
#include<stdio.h>
#definetokenpaster(n)printf("token"#n " = %d", token##n)
Int main(void){
Int token34 =40;
Tokenpaster(34);
Return0;
}
When the above code is compiled and executed, it produces the following result −
Token34 = 40
It happened so because this example results in the following actual output from the preprocessor−
Printf("token34 = %d", token34);
This example shows the concatenation of token##n into token34 and here we have used both stringize and token-pasting.
The Defined() Operator
The preprocessordefined operator is used in constant expressions to determine if an identifier is defined using #define. If the specified identifier is defined, the value is true (non-zero). If the symbol is not defined, the value is false (zero). The defined operator is specified as follows −
#include<stdio.h>
#if !defined (MESSAGE)
#define MESSAGE "You wish!"
#endif
Int main(void){
Printf("Here is the message: %s\n", MESSAGE);
Return0;
}
When the above code is compiled and executed, it produces the following result −
Here is the message: You wish!
Parameterized Macros
One of the powerful functions of the CPP is the ability to simulate functions using parameterized macros. For example, we might have some code to square a number as follows −
Int square(int x){
Return x * x;
}
We can rewrite above the code using a macro as follows −
#define square(x)((x)*(x))
Macros with arguments must be defined using the #define directive before they can be used. The argument list is enclosed in parentheses and must immediately follow the macro name. Spaces are not allowed between the macro name and open parenthesis. For example −
#include<stdio.h>
#define MAX(x,y)((x)>(y)?(x):(y))
Int main(void){
Printf("Max between 20 and 10 is %d\n", MAX(10,20));
Return0;
}
When the above code is compiled and executed, it produces the following result −
Max between 20 and 10 is 20
Find the Frequency of a Character
Intmain(){
Charstr[1000], ch;
Int count = 0;
Printf("Enter a string: ");
Fgets(str, sizeof(str), stdin);
Printf("Enter a character to find its frequency: ");
Scanf("%c", &ch);
For (inti = 0; str[i] != '\0'; ++i) {
If (ch == str[i])
++count;
}
Printf("Frequency of %c = %d", ch, count);
Return0;
}
Output
Enter a string: This website is awesome.
Enter a character to find its frequency: e
Frequency of e = 4
In this program, the string entered by the user is stored in str.
Then, the user is asked to enter the character whose frequency is to be found. This is stored in variable ch.
Then, a for loop is used to iterate over characters of the string. In each iteration, if the character in the string is equal to the ch, count is increased by 1.
Finally, the frequency stored in the count variable is printed.
Program to count vowels, consonants etc.
Intmain(){
Char line[150];
Int vowels, consonant, digit, space;
Vowels = consonant = digit = space = 0;
Printf("Enter a line of string: ");
Fgets(line, sizeof(line), stdin);
For (inti = 0; line[i] != '\0'; ++i) {
If (line[i] == 'a' || line[i] == 'e' || line[i] == 'i' ||
Line[i] == 'o' || line[i] == 'u' || line[i] == 'A' ||
Line[i] == 'E' || line[i] == 'I' || line[i] == 'O' ||
Line[i] == 'U') {
++vowels;
} elseif ((line[i] >= 'a'&& line[i] <= 'z') || (line[i] >= 'A'&& line[i] <= 'Z')) {
++consonant;
} elseif (line[i] >= '0'&& line[i] <= '9') {
++digit;
} elseif (line[i] == ' ') {
++space;
}
}
Printf("Vowels: %d", vowels);
Printf("\nConsonants: %d", consonant);
Printf("\nDigits: %d", digit);
Printf("\nWhite spaces: %d", space);
Return0;
}
Output
Enter a line of string: adfslkj34 34lkj343 34lk
Vowels: 1
Consonants: 11
Digits: 9
White spaces: 2
Here, the string entered by the user is stored in the line variable.
Initially, the variables vowel, consonant, digit, and space are initialized to 0.
Then, a for loop is used to iterate over characters of a string. In each iteration, whether the character is vowel, consonant, digit, and space is checked. Suppose, the character is a vowel, in this case, the vowel variable is increased by 1.
When the loop ends, the number of vowels, consonants, digits and white spaces are stored in variables vowel, consonant, digit and space respectively.
TEXT BOOKS:
C & Data Structures (A practical approach) – by G.S. Baluja and G.K. Baluja, Dhanapatrai & Co publishers.