C program to find frequency of a character from a string - c

why the code doesn't work?? anything wrong with that loop?? if then what should be answer? and why it can't be. Please make me clear. :)
#include<stdio.h>
#include<string.h>
int main()
{
char s[1000];
int i,j=1,x,y; char k,l;
gets(s);
l = strlen(s);
scanf("%c",&k);
for(s[i]=0; s[i]<l; i++)
{
if(s[i]=='k')
j++;
}
printf("\n%c is %d time(s) in string",k,j);
return 0;
}

First use l = strlen(s)+1; instead of l = strlen(s);. Then change s[i]=0 in for loop to i = 0; and use i<l instead of s[i]<l.
Also, change if(s[i]=='k') to if(s[i]==k).
Full example:
#include<stdio.h>
#include<string.h>
int main()
{
char s[1000];
int i,j=0,l;
char k;
gets(s);
l = strlen(s)+1;
scanf("%c",&k);
for(i=0; i<l; i++)
{
if(s[i]== k)
j++;
}
printf("\n%c is %d time(s) in string",k,j);
return 0;
}

please check this way. you are matching letter 'k' instead of variable.
if(s[i]==k)

The datatype of the variable l is char.It should be declared of the type int.
You have initialised j with value 1 when it should have been initialised with 0 .
The for loop is incorrect. Instead of s[i] use i and check the condition i < l .
And finally in the if condition replace 'k' by k
I hope this will help you get desired result

I can see you made many mistakes, I will list them up:
if(c[i] == 'k') should be if(c[i] == k)
You should use fgets instead of gets, gets is not stable or safe
Please do use MACRO for 1000 in char s[1000]
for(s[i]=0; s[i] < l; i++) is wrong because you should be iterating with i so it should be for( i = 0; i < length; ++i)
The code example:
#include <stdio.h> /* printf */
#include <stdlib.h> /* fgets */
#include <string.h> /* strlen */
#define MAX_LINE_LENGTH 1000
int main()
{
char k;
char line[MAX_LINE_LENGTH];
size_t count, length, i;
/* Reading a line/string */
printf("Please enter a line : ");
if (!fgets (line, MAX_LINE_LENGTH, stdin))
{
/* handle error */
printf("Failed to read input\n");
return 1;
}
/* calculating the length */
length = strlen(line) + 1;
/* Reading the letter to count its occurences */
printf("Please enter a letter : ");
scanf("%c",&k);
/*
* Counting the occurences of k in a string/line
*/
count = 0;
for(i = 0; i < length; ++i)
{
if(line[i] == k)
{
++count;
}
}
printf("%c is %d time(s) in string\n", k, count);
return 0;
}

Related

How do I compare an integer with a character in a string in C?

I want to compare the integers in a string with integers (0-9) and I wrote this -
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
char num[100];
int count = 0;
scanf("%s", num);
int len = strlen(num);
for (int i = 0; i <= 9; i++)
{
for (int j = 0; j <= len; j++)
{
if (i == (num[j] - '0'))
{
count++;
}
}
printf("%d ", count);
count = 0;
}
return 0;
}
No problems with this (works in most cases but it is failing in few cases). So can you please give me alternate and best idea to do this?
Thanks in advance
Complete pic -
The root cause is not in char comparison, but in the under-allocated buffer:
char num[100];
The assignment constraint is:
1 <= len(num) <= 1000
After increasing the buffer size, all the tests pass.
Besides a too small input buffer (i.e. 100 instead of 1001), I think your approach is too complex.
Instead of a nested loop, I'll suggest an array to count the frequency, i.e. an array with 10 elements so that you have a counter for each digit.
int main() {
char num[1001]; // 1000 chars + 1 zero termination
int count[10] = {0}; // Array of 10 zero initialized counters, one for each digit
scanf("%1000s", num); // At max accept 1000 chars input
char* p = num;
while (*p)
{
if (isdigit(*p) ++count[*p - '0'];
++p;
}
for (int i = 0; i < 10; ++i) printf("%d ", count[i]);
puts("");
return 0;
}
If you don't want to use isdigit you can instead do:
if (*p >= '0' && *p <= '9') ++count[*p - '0'];

how to reverse order of words in string using C?

I am trying to reverse the order of words in a string, but my output is a bunch of junk that makes no sense. I don't know what is the problem, maybe the loops are broken.
Appreciate it if someone can explain what is wrong with my code below. I still new to C programming and this kind of problem is kind of frustrating.
#include<stdio.h>
int main()
{
//declare variable
char string[100], rev_string[100];
//declare number of loop
int i, j, len;
printf("enter the string: ");
scanf("%s",string);
//finding the length
len = strlen(string);
printf("strings length: %d\n", len);
for (i = len - 1; i >= 0; i--)
for (j = 0; j < len - 1; j++)
rev_string[j] = string[i];
rev_string[j] = '\0';
if (strcmp(string, rev_string) == 0)
printf("rev_string: %s is a palindrome", rev_string);
else
printf("rev_string : %s is not a palindrome words",rev_string);
return(0);
}
Your title is a bit confusing because your code seems to be a palindrome check and it should reverse the string, not the order of the words.
To reverse the string you can simply do:
for (i = 0; i < len; i++)
rev_string[i] = string[len - i - 1];
This code can help you :
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#define NCHARS 256 /* constant to count array size, covers ASCII + extended ASCII */
int ispalindrom (const char *s1, const char *s2)
{
int count[NCHARS] = {0}; /* counting array, covers all extended ASCII */
for (; *s1; s1++) /* loop over chars in string 1 */
if (!isspace(*s1)) /* if not whitespace */
count[(int)*s1]++; /* add 1 to index corresponding to char */
for (; *s2; s2++) /* loop over chars in string 2 */
if (!isspace(*s2)) /* if not whitespace */
count[(int)*s2]--; /* subtract 1 from index corresponding to char */
for (int i = 0; i < NCHARS; i++) /* loop over counting array */
if (count[i]) /* if any index non-zero, not anagram */
return 0;
return 1; /* all chars used same number of times -> anagram */
}
void main()
{
int i, j = 0, k = 0, x, len;
char str[100], str1[10][20], temp;
char str2[100];
printf("enter the string :");
scanf("%[^\n]s", str);
for (int i = 0;str[i] != '\0'; i++)
{
str2[i]=str[i];
}
/* reads into 2d character array */
for (int i = 0;str[i] != '\0'; i++)
{
if (str[i] == ' ')
{
str1[k][j]='\0';
k++;
j=0;
}
else
{
str1[k][j]=str[i];
j++;
}
}
str1[k][j] = '\0';
/* reverses each word of a given string */
for (int i = 0;i <= k;i++)
{
len = strlen(str1[i]);
for (int j = 0, x = len - 1;j < x;j++,x--)
{
temp = str1[i][j];
str1[i][j] = str1[i][x];
str1[i][x] = temp;
}
}
for (int i = 0;i <= k;i++)
{
printf("%s ", str1[i]);
}
printf("\n\n");
if (ispalindrom(str1, str2)==0)
{
printf("The word is Palindrom !\n");
}
else
{
printf("The word is not Palindrom !\n");
}
}
#include <stdbool.h>
#include <stdio.h>
bool ispalindrom(char *str,int k)
{
for(int i=0;i<k;i++)
{
if(str[i]!=str[k-i-1])
{
return false;
}
}
return true;
}
int main()
{
char string[100];
printf("enter the string: ");
scanf("%s",string);
if (ispalindrom(string,strlen(string)))
{
printf("\nrev_string: %s is a palindrome\n", string);
}
else
{
printf("\nrev_string : %s is not a palindrome words\n",string);
}
}
you can use a loop first to reverse the string first and then use strcomp()
#include<stdio.h>
#include <string.h>
int main()
{
//declare variable
char string[100], rev_string[100];
//declare number of loop
int i, j =0 , len;
printf("enter the string: ");
scanf("%s",string);
//finding the length
len = strlen(string);
printf("strings length: %d\n", len);
for (i = len - 1;i >= 0;i--){
rev_string[j] = string[i];
j++;
}
//check the rev_string if you want
/*for (i = 0; i < len; i++){
printf("%c\n",rev_string[i]);
}*/
if(strcmp(rev_string,string) == 0){
printf("Is Palindrome\n");
return(0);
}else{
printf("Is not Palindrome\n");
return(1);
}
}

String array prints out trash values

So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice.
Also im not sure how I should print out the length of the new string.
This is my main.c file:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main() {
char string[256];
int length;
printf("Enter char array size of string(counting with backslash 0): \n");
/*
Example: The word aabc will get a size of 5.
a = 0
a = 1
b = 2
c = 3
/0 = 4
Total 5 slots to allocate */
scanf("%d", &length);
printf("Enter string you wish to remove duplicates from: \n");
for (int i = 0; i < length; i++)
{
scanf("%c", &string[i]);
}
deleteDuplicates(string, length);
//String output after removing duplicates. Prints out trash values!
for (int i = 0; i < length; i++) {
printf("%c", string[i]);
}
//Length of new string. The length is also wrong!
printf("\tLength: %d\n", length);
printf("\n\n");
getchar();
return 0;
}
The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.
The deleteDuplicates function looks like this in the functions.c file:
void deleteDuplicates(char string[], int length)
{
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length;)
{
if (string[j] == string[i])
{
for (int k = j; k < length; k++)
{
string[k] = string[k + 1];
}
length--;
}
else
{
j++;
}
}
}
}
There is a more efficent and secure way to do the exercise:
#include <stdio.h>
#include <string.h>
void deleteDuplicates(char string[], int *length)
{
int p = 1; //current
int f = 0; //flag found
for (int i = 1; i < *length; i++)
{
f = 0;
for (int j = 0; j < i; j++)
{
if (string[j] == string[i])
{
f = 1;
break;
}
}
if (!f)
string[p++] = string[i];
}
string[p] = '\0';
*length = p;
}
int main() {
char aux[100] = "asdñkzzcvjhasdkljjh";
int l = strlen(aux);
deleteDuplicates(aux, &l);
printf("result: %s -> %d", aux, l);
}
You can see the results here:
http://codepad.org/wECjIonL
Or even a more refined way can be found here:
http://codepad.org/BXksElIG
Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.
Here's an example using your code.
The function call would be:
deleteDuplicates(string, &length);
The function would be:
void deleteDuplicates(char string[], int *length)
{
for (int i = 0; i < *length; i++)
{
for (int j = i + 1; j < *length;)
{
if (string[j] == string[i])
{
for (int k = j; k < *length; k++)
{
string[k] = string[k + 1];
}
*length--;
}
else
{
j++;
}
}
}
}
You can achieve an O(n) solution by hashing the characters in an array.
However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.
You can create a hash array like this:
int hashing[256] = {0};
Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.
This is a common algorithm that is used everywhere, and it will help make your code more efficient.
Also it is better to use fgets for reading input from user, instead of scanf().
Here is some modified code I wrote a while ago which shows this idea of hashing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHAR 256
char *remove_dups(char *string);
int main(void) {
char string[NUMCHAR], temp;
char *result;
size_t len, i;
int ch;
printf("Enter char array size of string(counting with backslash 0): \n");
if (scanf("%zu", &len) != 1) {
printf("invalid length entered\n");
exit(EXIT_FAILURE);
}
ch = getchar();
while (ch != '\n' && ch != EOF);
if (len >= NUMCHAR) {
printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
exit(EXIT_FAILURE);
}
printf("Enter string you wish to remove duplicates from: \n");
for (i = 0; i < len; i++) {
if (scanf("%c", &temp) != 1) {
printf("invalid character entered\n");
exit(EXIT_FAILURE);
}
if (isspace(temp)) {
break;
}
string[i] = temp;
}
string[i] = '\0';
printf("Original string: %s Length: %zu\n", string, strlen(string));
result = remove_dups(string);
printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));
return 0;
}
char *remove_dups(char *str) {
int hash[NUMCHAR] = {0};
size_t count = 0, i;
char temp;
for (i = 0; str[i]; i++) {
temp = str[i];
if (hash[(unsigned char)temp] == 0) {
hash[(unsigned char)temp] = 1;
str[count++] = str[i];
}
}
str[count] = '\0';
return str;
}
Example input:
Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend
Output:
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10

What's wrong with my program which reverses a given integer?

Codechef isn't accepting the following code. Can anyone tell me what's wrong in it as I'm unable to point any mistake ?
//This program reverses a given integer.
#include<stdio.h>
int main(void)
{
int t,n,l;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
while(n>0){
l=n%10;
n=n/10;
printf("%d",l);
}
printf("\n");
}
return 0;
}
t is no. of test cases.
n is the input integer.
l is some random variable to get the print job done.
This program is supposed to reverse a positive integer only.
Example:- Input - 1234
Output - 4321
try this code (I'm agree with molbdnilo's comment):
//This program reverses a given integer.
#include<stdio.h>
#include <math.h>
int main(void)
{
int i,j,t,n,l,r = 0;
char d[1024]; // stock digits
scanf("%d",&t);
while(t--){
scanf("%d",&n);
i = 0;
while(n>0){
l=n%10;
n=n/10;
d[i] = l;
i++;
}
for(j=0;j<i;j++)
r+= d[i-j-1] * pow(10,j); // r is the reversed number
printf("%d\n",r);
}
return 0;
}
I got it. You must not print the non-significant '0'. For example 1230 gives 321. Here is my working code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* strrev reverses a given string */
char *strrev(char *str)
{
char tmp;
size_t i = 0,
len = strlen(str);
for (; i < len / 2 ; ++i)
{
tmp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = tmp;
}
return str;
}
int main(void)
{
char buff[32],
*s;
size_t i,
len;
scanf("%zu", &len);
for (i = 0 ; i < len ; ++i)
{
scanf("%s", buff);
s = strrev(buff);
while (*s == '0')
++s; /* discarding '0' */
printf("%s\n", s);
}
return EXIT_SUCCESS;
}

C - Find most frequent element in char array

i'm developing a little function to display the most frequent character in a (char) array.
This is what I've accomplished so far, but I think i'm on the wrong way.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char test[10] = "ciaociaoci";
max_caratt(test, 10);
}
int max_caratt(char input[], int size)
{
int i;
char max[300];
max[0] = input[0];
for (i=0; i<size; i++)
{
if(strncmp(input,input[i],1) == 1)
{
printf("occourrence found");
max[i] = input[i];
}
}
}
Any help?
Actually, the correct code is this.
It's just a corrected version of IntermediateHacker's below snippet.
void main()
{
int array[255] = {0}; // initialize all elements to 0
char str[] = "thequickbrownfoxjumpedoverthelazydog";
int i, max, index;
for(i = 0; str[i] != 0; i++)
{
++array[str[i]];
}
// Find the letter that was used the most
max = array[0];
index = 0;
for(i = 0; str[i] != 0; i++)
{
if( array[str[i]] > max)
{
max = array[str[i]];
index = i;
}
}
printf("The max character is: %c \n", str[index]);
}
The easiest way to find the most common character is to create an int array of 255 and just increment the arraly element that corresponds to the character. For example: if the charcter is 'A', then increment the 'A'th element (if you look at any ascii table you will see that the letter 'A' has a decimal value of 65)
int array[255] = {0}; // initialize all elements to 0
char str[] = "The quick brown fox jumped over the lazy dog.";
int i, max, index;
// Now count all the letters in the sentence
for(i = 0; str[i] != 0; i++)
{
++array[str[i]];
}
// Find the letter that was used the most
max = array[0];
index = 0;
for(i = 0; str[i] != 0; i++)
{
if( array[i] > max)
{
max = array[i];
index = i;
}
}
printf("The max character is: %c \n", (char)index);
You're passing a (almost) string and a char to strncmp(). strncmp() takes two strings (and an integer). Your program shouldn't even compile!
Suggestion: increase the warning level of your compiler and mind the warnings.
You may want to look at strchr() ...
Assuming an input array of 0-127, the following should get you the most common character in a single pass through the string. Note, if you want to worry about negative numbers, shift everything up by +127 as needed...
char mostCommonChar(char *str) {
/* we are making the assumption that the string passed in has values
* between 0 and 127.
*/
int cnt[128], max = 0;
char *idx = str;
/* clear counts */
memset((void *)cnt, 0, sizeof(int) * 128);
/* collect info */
while(*idx) {
cnt[*idx]++;
if(cnt[*idx] > cnt[max]) {
max = *idx;
}
idx++;
}
/* we know the max */
return max;
}
If you don't need to preserve the input array, you could sort the input array first, then find the longest contiguous run of a single character. This approach is slower, but uses less space.
I made a working version using structs. It works fine, I guess, but I think there's a MUCH better way to write this algorithm.
#include <stdio.h>
#include <stdlib.h>
struct alphabet {
char letter;
int times;
};
typedef struct alphabet Alphabet;
void main() {
char string[300];
gets(string);
Alphabet Alph[300];
int i=0, j=0;
while (i<=strlen(string)) {
while(j<=300) {
if(string[i] != Alph[j].letter) {
Alph[i].letter = string[i];
Alph[i].times = 1;
}
else {
Alph[j].times++;
}
j++;
}
j=0;
i++;
}
int y,max=0;
char letter_max[0];
for (y=0; y<strlen(string); y++) {
printf("Letter: %c, Times: %d \n", Alph[y].letter, Alph[y].times);
if(Alph[y].times>max) {
max=Alph[y].times;
letter_max[0]=Alph[y].letter;
}
}
printf("\n\n\t\tMost frequent letter: %c - %d times \n\n", letter_max[0], max);
}
I saw you all creating big arrays and "complex" stuff so here I have easy and simple code xD
char most_used_char (char s[]) {
int i; //array's index
int v; //auxiliary index for counting characters
char c_aux; //auxiliary character
int sum = 0; //auxiliary character's occurrence
char c_max; //most used character
int max = 0; //most used character's occurrence
for (i = 0; s[i]; i++) {
c_aux = s[i];
for (v = 0; s[v]; v++)
if (c_aux == s[v]) sum++; /* responsible cycle for counting
character occurrence */
if (sum > max) { //checks if new character is the most used
max = sum;
c_max = c_aux;
}
sum = 0; /* reset counting variable so it can counts new
characters occurrence */
}
return c_max; //this is the most used character!
}

Resources