1. Write a program to reverse the words in a string. e.g.if the string is "Write a C program to print words" The output should be "words print to program C Write"
#include<stdio.h> #include<string.h> int convert_to_words(char *s,char words[][20]); void reverse_words(char words[][20],int nwords); void print_words(char words[][20],int n); int main() { char s[100]; char words[20][20]; int num_of_words; printf("Your string:"); gets(s); num_of_words = convert_to_words(s,words); print_words(words,num_of_words); reverse_words(words,num_of_words); print_words(words,num_of_words); return 0; } int convert_to_words(char *s,char words[][20]) { int nword=0;int j=0; while(*s) { if(*s==' '||*s=='\t')/*if a white space*/ { if(*(s-1)==' '|| *(s-1)=='\t') continue;/*skip consecutive spaces*/ /*end with null character and increment word count*/ words[nword][j]=0; nword++; j=0; } else { /*add letter to word*/ words[nword][j++]=*s; } s++; } words[nword][j]=0; nword++; return nword; } void reverse_words(char words[][20],int nwords) { int i,j; /*swap first and last word, second and last minus oneth and so on*/ for(i=0,j=nwords-1;i<j;i++,j--) { char temp[20]; strcpy(temp,words[i]); strcpy(words[i],words[j]); strcpy(words[j],temp); } } void print_words(char words[][20],int n) { int i; for(i=0;i<n;i++) printf("%s",words[i]); }
2. Write a program to remove duplicate words from a string.
#include<stdio.h> #include<string.h> int convert_to_words(char *s,char words[][20]); void remove_duplicates(char words[][20],int nwords); void print_words(char words[][20],int n); void pack_string(char words[][20],char *str,int omit_this,int numwords); int main() { char s[100]; char words[20][20]; int num_of_words; printf("Your string:"); gets(s); num_of_words = convert_to_words(s,words); remove_duplicates(words,num_of_words); puts("after duplicates are removed "); print_words(words,num_of_words); return 0; } int convert_to_words(char *s,char words[][20]) { int nword=0;int j=0; while(*s) { if(*s==' '||*s=='\t') { words[nword][j]=0; nword++; j=0; } else { words[nword][j++]=*s; } s++; } words[nword][j]=0; nword++; return nword; } void remove_duplicates(char words[][20],int nwords) { int i,j; char tempstr[100]; for(i=0;i<nwords;i++) { char temp[20]; strcpy(temp,words[i]); for(j=i+1;j<nwords;j++) { /*if word matches with earlier word, remove it*/ if(strcmp(temp,words[j])==0) { pack_string(words,tempstr,j,nwords); nwords = convert_to_words(tempstr,words); } } } } void print_words(char words[][20],int n) { int i; puts(""); for(i=0;i<n;i++) printf("%s ",words[i]); } void pack_string(char words[][20],char *str,int rm,int num_words) { int i; strcpy(str,""); for(i=0;i<num_words;i++) { if(i!=rm)/*copy all words except for rm-th word*/ { strcat(str,words[i]); strcat(str," "); } } }
char * mystrcpy(char*dest,char*src) { char *temp = dest; while(*src) { *dest++ = *src++; } *dest = '\0'; return temp; }We can even write a smaller function like this.
char *mystrcpy2(char *dest,char *src) { char *temp = dest; while(*dest++=*src++) ; return temp; }
In this function, while loop is using assignment statement to copy each src character to dest character. The assignment becomes false after copying null character to dest.
int palindrome(char *s) { int l=strlen(s); int i,j; for(i=0,j=l-1;i<j;i++,j--) if(s[i]!=s[j]) return 0; return 1; }
A palindrome is a string which reads same both forward and backword. A longer example is
able was i ere i saw elba
In the function above, we compare first character with last character, second character with last but oneth character and so on. Whenever these characters don't match, we return a 0 to indicate the string is not a palindrome and exit the function. If all the characters match with their corresponding characters in the reverse direction, we return a 1 to indicate that the string is a palindrome.
The comparison should be done till half the string - until i and j become equal or j becomes greater than i.
int main() { char str[50]; printf("Enter a string"); scanf("%s",str); printf("The length of the string is %d\n",strlen(str)); return 0; }Find out the error in the program.
gets(str) should be used to read a line of characters instead of
scanf("%s",str);
scanf() library function reads the string until a white space. Which means it will only read first word of our string. To read a complete line, we should use gets() function. gets() reads a string until it encounters line break - it reads a complete line.
#include<stdio.h> #include<string.h> #include<stdlib.h> char * find_common_chars(char *string1, char *string2) { char *temp = (char*)malloc(100); char *t2 = temp; int i,len; len = strlen(string2); while(*string1) { char ch = *string1; int found = 0; char *ptr = strchr(string2,ch); if(ptr!=NULL ) *temp++ = ch; string1++; } *temp = 0; return t2; } int main() { char str1[100],str2[100]; char *ptr; printf("Enter strings one line at a time"); fgets(str1,80,stdin); gets(str2,80,stdin); ptr = find_common_chars(str1,str2); printf("Common characters between %s and %s is %s",str1,str2,ptr); return 0; }
The program iterates through each character of string1. Finds if there is a matching character in string2. If there is, this character is copied to temp string.
The library function strchr(string,char) used here, searches for char in string, and returns pointer to the first occurance of char if it is found. If not found, it returns a NULL pointer.
if(c>='a' && c<='z' ) printf("Lowercase Letter"); else if( c>='A' && c<='Z' ) printf("Uppercae Letter"); else if (c>='0' && c<='9') printf("Digit"); else if (c==' ' || c=='\t' || c=='\n') printf("White space");You can also use builtin functions
if(isupper(c)) printf("upper case Letter"); else if(islower(c)) printf("lower case Letter"); else if(isdigit(c)) printf("Digit"); else if(isspace(c)) printf("White space");
These functions are defined in the header file ctype.h .
atoi() function extracts the integer from a given string. If the string does not contain a number or it starts with a non-digit, the function returns a 0
Similarly atof() function converts the given string to a float number.
When converting string to numbers, we have to remember that, the digits are stored using ASCII code. So digit 0 is stored as 48, 1 as 49 and so on. So after taking a character, its numerical value must be subtracted by 48.
Also to convert the number to decimal system, after extracting each digit, before adding this digit to the number, previous set of digits must be shifted to left. Which is done by multiplying the number by 10.
For atof() - in case of decimal values after the decimal point, each digit must be multiplied by 10-i where i is the position with respect to decimal point. First digit to the right of decimal point must be multiplied by 10-1, next by 10-2 and so on. Or we can multiply it by a factor f which must be multiplied by 0.1 as we move to the right of decimal point.
If the number is negative, there will be a '-' at the leftmost position. If this is present, we can multiply the number by -1.
int myatoi(char *str) { int l,i; int sum=0; int sign=1; i = 0; if(str[0]=='-') { sign = -1;i++; } for(;str[i]!=0;i++) { if( (str[i]>='0' && str[i]<='9')) sum = sum*10 + str[i]-48; else break; } return sum*sign; } float myatof(char *str) { int i=0; float sum=0; int isfraction=0; int sign = 1; float decimals = 0.1; if(str[0]=='-') { sign = -1;i++; } for(;str[i];i++) { if(isdigit(str[i])) { if(isfraction) { sum =sum+ (str[i]-48)*decimals; decimals *=0.1; } else { sum = sum*10 + (str[i]-48); } } else if (str[i]=='.') { isfraction = 1; } else break; } return sum*sign; } int main() { char str[40]; printf("Enter a string:"); scanf("%s",str); printf("The number is %.5f",myatof(str)); return 0; }
There are more advanced functions to convert string to numbers - these are strtol() - string to long integer, strtof() - string to float, strtod() - string to double etc. These handle the errors and set the errornumber unlike atof and atoi. Also strtol can specify the base of the number as third parameter.
The function must be similar to strstr() function which searches for str2 in a string str1 and returns pointer to first occurance of str2 in str1. But in this function we must return integer index of the first occurance.
The function uses string library function strncmp. strncmp is similar to strcmp, but it compares first n characters of two strings.
If the length of second string is l, function takes first n characters from first string and compares them with second string. If they match, then 0 is returned as index. If they don't match, n characters from 1st position (1st to n+1th characters) are compared with second string, and if they match, 1 is returned as index. This process is continued till a match is found or till the last character of first string.
int indexof(char *src,char *searchstr) { int i=0; int len = strlen(searchstr); while(src[0]) { int result=strncmp(src+i,searchstr,len); if(result==0)/*searchstr is found*/ return i; i++; } return -1; }
The library function used here - strncmp - compares the first n characters of both the strings and returns 0 if they match.
#include<stdio.h> #include<string.h> char highest(char *str); int main() { char str[100]; printf("Enter string:"); fgets(str,100,stdin); printf("The most frequent character in the string is |%c|\n",highest(str)); return 0; } char highest(char *str) { int maxchar = 0; int arr[256]={0}; int i; while (*str) { char ch = *str; arr[ch]++;/*increment count of character*/ str++; } for(i=1;i<256;i++) if(arr[i]>arr[maxchar]) maxchar = i; return maxhar; }
We iterate through characters. As and when we encounter a character with code ch, element of arr[] whose index is ch is incremented. At the end of iteration, arr[] will store the frequencies of each character.
e.g. arr[65] will be the number of times character A is present in the string. Next we find the largest element in arr[]. Its index will be the ASCII code of most frequent character.
e.g.
this is C program
should become
C is this program
#include<stdio.h> #include<string.h #include<stdlib.h> int break_into_words(char *str,char *words[20]); void sort_words(char *words[20],int num); void print_words(char *words[20],int num); int main() { char str[100]; int num_words; char *words[20]; gets(str); num_words = break_into_words(str,words); print_words(words,num_words); sort_words(words,num_words); print_words(words,num_words); return 0; } int break_into_words(char *str,char *words[20]) { int i=0,j=0; int whitespacestarted = 0; char ch; words[0] = (char*)malloc(20); while(*str) { ch = *str++; if (ch==' '||ch=='\t'||ch=='\n') { words[i++][j]=0; j=0; words[i] = (char*)malloc(20); } else { words[i][j++]=ch; } } if(ch!=' '&&ch!='\n'&&ch!='\t') words[i++][j]=0; return i; } void sort_words(char *words[20],int n) { int i,j; char *temp; for(i=1;i<n;i++) { temp=words[i]; j=i-1; while(j>=0 && strlen(temp)<strlen(words[j])) { words[j+1] = words[j]; j--; } words[j+1]=temp; } } void print_words(char *words[20],int n) { int i; for(i=0;i<n;i++) printf("%s ",words[i]); printf("\n"); }
int first_non_repeated_char(char *str) { int i; for(i=0;str[i];i++) { char ch = str[i]; int j; int repeated = 0; for(j=0;str[j];j++) if(i!=j && str[j]==ch) { repeated = 1;break; } if(!repeated ) return ch; } return -1; }
The function iterates through each character ch in the string, then uses another loop to check each character to see if any character matches with ch. If there is a match, repeated is set 1 and loop is broken. If any non-repeated character is found, it is returned. If there are no non-repeated characters, the function returns -1.
#include<stdio.h> #include<string.h> int check_anagram(char *str1,char *str2); void delete_char(char *str,char ch); int main() { char str1[60],str2[60]; int angrm=0; printf("Enter two strings:"); fgets(str1,59,stdin); fgets(str2,59,stdin); angrm = check_anagram(str1,str2); printf("The strings are %s\n",angrm?"anagrams":"not anagrams"); return 0; } int check_anagram(char *str1, char *str2) { int i; for(i=0;str1[i];i++) { char ch = str1[i]; char *ptr = strchr(str2,ch); if(ptr==NULL) return 0; delete_char(str2,ch); } if(strlen(str2)==0) return 1; return 0; } void delete_char(char *str,char ch) { char *ptr = strchr(str,ch); if(ptr==NULL) return;//error while(*ptr) { *ptr = *(ptr+1); ptr++; } }
check_anagram() function iterates over the charactes in first string. For each character ch in first string, it checks for a matching character in second string using strchr() function. If there is no matching character, then it indicates that first string has character without a corresponding character in second string. Which indicates that the two can not be anagrams.
If a matching character is found, then it is deleted from the second string. This takes care of possibility of duplicate characters.
This procedure is repeated till end of first string. Now if the two strings are anagrams, second string should not have any characters.
#include<stdio.h> #include<string.h> #include<stdlib.h> char *trim_string(char *str); int main() { char str[60]; char *ptr; fgets(str,59,stdin); ptr= trim_string(str); printf("After removing the white spaces, the string is |%s|\n",ptr); return 0; } char *trim_string(char *str) { int len; char *temp = (char*)malloc(60); while(*str==' ' || *str=='\t' || *str=='\n') /*find spaces at begining*/ str++; len = strlen(str); temp = str+len-1; while(*temp==' ' || *temp=='\t' || *temp=='\n') /*find spaces at end*/ temp--; temp++; *temp = 0; return str; }
int begins_with(char *str1,char *str2) { int l = strlen(str2); if ( strncmp(str1,str2,l)==0) return 1; return 0; }
#include<stdio.h> #include<string.h> int ends_with(char *str1, char *str2);//returns 1 if str1 begins with str2 int main() { char str1[100],str2[100]; gets(str1); gets(str2); if(ends_with(str1,str2)) printf("%s ends with %s\n",str1,str2); else printf("%s does not end with %s\n",str1,str2); return 0; } int ends_with(char *str1,char *str2) { int l = strlen(str2); str1 = str1+ (strlen(str1) - l); if(strcmp(str1,str2)==0) return 1; return 0; }
#include<stdio.h> #include<string.h> void replace(char *str,char ch1,char ch2) { while(*str) { if (*str==ch1) *str = ch2; str++; } } int main() { char str[100]; char ch1,ch2; gets(str); printf("Enter character to replace :"); scanf("%c",&ch1); printf("Enter new character in place of %c :",ch1); scanf(" %c",&ch2); replace(str,ch1,ch2); printf("After replacing %c with %c the string is %s\n",ch1,ch2,str); return 0; }
void encode(char *str) { while(*str) { *str = *str -1; str++; } }
#include<stdio.h> int split(char *string,char sepr,char substring[][30]) { int i=0,j=0; while(*string) { char temp = *string++; if(temp==sepr) { substring[i++][j]=0;j=0; } else substring[i][j++]=temp; } if(substring[i][j]!=0) substring[i++][j]=0; return i; } int main() { char string[200]; char separator; char words[30][30]={0}; int nw; printf("Enter the string:"); gets(string); printf("Separator:"); scanf("%c",&separator); nw = split(string,separator,words); do printf("%s\n",words[nw]); while(nw--); }
/* function return 1 if str2 is a subset of str1. Else returns 0*/ int isSubset(char *str1,char *str2) { while(*str2){ char ch = *str2++; if(strchr(str1,ch)==NULL) return 0; } return 1; }
We are checking to make sure that each character in second string str2is present in first string str1. If any character is not present, the library function strchr() will return NULL. If null is returned, isSubset() function returns a 0.
If all characters are present, then the functio returns a 1.
#include<stdio.h> void shiftele(char str[],int pos); void remove_char(char *str,char ch); int main() { char str[100]; char ch; printf("Enter the string\n"); gets(str); printf("Enter the character to be removed\n"); scanf(" %c",&ch); remove_char(str,ch); printf("After removing all %c, string is %s",ch,str); return 0; } void remove_char(char *str,char ch) { int i; for(i=0;i<=str[i]!='\0';i++) { if(str[i] == ch ) { int j;/* pack the string. Move all characters to left*/ for(j=i;str[j]!=0;j++) str[j] = str[j+1]; } } }
Another method will be to use a temporary array and copy every character except for r (r is the character to be removed). Then strcpy can be used to copy this temporary string back to original string. This method has a better time efficiency.
#include<stdio.h> struct charfreq { char ch; int freq; }; int find_frequencies(char *str,struct charfreq freq_arr[]) { int count = 0; char ch; while(ch = *str++) { int index ; if((index = index_of(ch,freq_arr,count))==-1) { freq_arr[count].ch = ch; freq_arr[count++].freq=1; } else { freq_arr[index].freq++; } } return count; } int main() { char str[100]; struct charfreq cf[30]; int i,l; printf("Enter string:"); gets(str); l = find_frequencies(str,cf); for(i=0;i<l;i++) printf("%c %d\n",cf[i].ch,cf[i].freq); return 0; }
#include<stdio.h> #include<string.h> int main() { char str1[100]; char str2[100]; char str3[200]; puts("First string"); gets(str1); puts("Second string"); gets(str2); strcpy(str3,str1); strcat(str3,str1); if(strstr(str3,str2)!=NULL) printf("%s is a rotation of %s",str1,str2); else printf("%s is not a rotation of %s",str1,str2); return 0; }
If string is
Success is by product of hard workOutput should be
Suces is by product of hard work
#include<stdio.h> #include<string.h> /* function deletes the first character of the string and packs it*/ void delete_char(char *str) { /*delete current char by moving rest of string to left*/ while(*str) { *str = *(str+1); str++; } } void eliminate_pairs(char *str) { char ch,prevch; prevch=0; while((ch=*str)) { if(ch==prevch) delete_char(str); else str++; prevch = ch; } } int main() { char str1[100]; puts("string"); gets(str1); eliminate_pairs(str1); printf("After elimination, the result is %s",str1); return 0; }
C is procedure oriented languageand second string is
abcdethen output should be
C is prour orint lngug
#include<stdio.h> #include<string.h> int indexOf(char ch,char *str) { int i; for(i=0;str[i];i++) if(str[i]==ch) return i; return -1; } /* function deletes the first character of the string and packs it*/ void delete_char(char *str) { while(*str) { *str = *(str+1); str++; } } void eliminate_chars(char *str1,char *str2) { char ch,prevch; prevch=0; while((ch=*str1)) { if(indexOf(ch,str2)!=-1) delete_char(str1); else str1++; } } int main() { char str1[100]; char str2[100]; puts("First string"); gets(str1); puts("Second string"); gets(str2); eliminate_chars(str1,str2); printf("After elimination, the result is %s",str1); return 0; }
#include<stdio.h> #include<string.h> #include<stdlib.h> void reverse(char *s) { int i,j; int len = strlen(s); for(i=0,j=len-1;i<j;i++,j--) { char temp = s[i]; s[i] = s[j]; s[j] = temp; } } char *itoa(int num) { char *str = malloc(40); int i; int dig; while(num) { dig = num%10; str[i++]=dig+48; num /=10; } str[i]=0; reverse(str); return str; } int main() { int n; printf("Enter number :"); scanf("%d",&n); printf("The number as a string is %s\n",itoa(n)); return 0; }
To find string length, we have to move through the characters of the string until we encounter null character - whose ascii code is 0. That is we have to repeat the loop as long as *str is true (non-zero).
#include<stdio.h> int stringlen(char *str) { int l = 0; while (*str++) l++; return l; }
#include<stdio.h> #include<string.h> int longestString(char str[][80],int nl) { int l = 0,i; for(i=0;i<nl;i++) if(strlen(str[i])>strlen(str[l])) l = i; return l; } int main() { char str[10][80]; int i; for(i=0;i<10;i++) { printf("String:"); fgets(str[i],79,stdin); } i = longestString(str,10); printf("The longest string is %s",str[i]); return 0; }
#include<stdio.h> #include<string.h> void remove_vowels(char *s); int is_vowel(char ch); int main() { char str[40]; printf("Enter a string"); fgets(str,39,stdin); replace_vowels(str); printf("The string after replacing of vowels is %s",str); return 0; } void replace_vowels(char *s) { int l = strlen(s); for(;*s!='\0';s++) { char ch = *s; if(is_vowel(ch)) { *s = ch+1; } } } int is_vowel(char ch) { ch = tolower(ch); /* we are testing only for lower case vowels*/ if(ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u') return 1; return 0; }
A string in C is a character array.
To define a string variable, we define a char array.
char arr[40];
We are defining a string with a maximum length of 39 characters (and one null character)
To access individual characters, we can use array indices.
arr[0] gives 0th character and so on.
A string can also be defined with a character pointer. But if you define a string using character pointer, you should either initialize it with a string literal (which makes it a constant string) or you should allocate memory to the string using malloc.
e.g.char *str1 = "Hello world"; /*str1 is a pointer to constant characters*/ char *str2; str2 = (char*) malloc(80); /*allocate memory to string*/
A string is initialized by giving value in double quotes.
char str[30] = "Hello";or
char str[] = "Hello";
In the second definition, size of str is 6 characters.
But there is yet another initialization which is syntactically correct - but not preferred
char str[]= {'H',''e','l','l','o','\n'};
A string variable which is character array is read and written using format specifier %s. Array name is specified as parameter for printf()/scanf() without index. Scanf() does not use address-of operator for a string.
char str[30]; scanf("%s",str); printf("%s",str);
Note that scanf will read only till white space.
If your input is "Hello world", the variable will read only Hello.
To read an entire line you can use gets() or fgets()
gets(str); fgets(str,29,stdin);
Similarly a string can also be displayed using puts
puts(str);
puts() prints the string followed by newline character.
sscanf is a function to read values from a string instead of console.
Syntax
sscanf(char *string,char *format-specifier ...); sprintf(char *string,char *format-specifier ...);
e.g.
char str[30]; int a=12; sprintf(str,"a is %d",a);
Now str will be "a is 12"
char *str2="10 10 1.2"; int a,b; float c; sscanf(str2,"%d %d %f",&a,&b,&c);
Now a, b and c are read from str2 and will be read as 10,10 and 1.2