5

I wrote a program that should take a string and a letter, then call a function which have two parameters (the string, the letter) and then count frequency of letter in the string.

The problem with my code is that it always returns num with value zero for any letter.

#include <stdio.h>
#include <stdlib.h>

int Occur(char [], char);

int main()
{
    char s[100], l;
    printf("Enter A String:\n");
    scanf("%s",s);
    printf("Enter A Letter:\n");
    scanf("%c",&l);
    getchar();

    printf("Num Of Occurance is %d ",Occur(s,l));

    return 0;
}

int Occur(char S[100], char L)
{
    int i;
    int num=0;

    for(i=0; S[i]!='\0'; i++)
    {
        if(S[i]==L)
        num++;
    }

    return num;
}
Bob__
  • 12,361
  • 3
  • 28
  • 42
  • 2
    Have you tried to debug your code? – CIsForCookies May 14 '17 at 18:33
  • 5
    Your problem is not the counting function, but how you read input. `%s` snacs a single word and `%c` scans the next character, which very likely is a space or newline. You can skip whitespace by preceding `%c` with a space: `scanf(" %c",&l);` – M Oehm May 14 '17 at 18:34
  • (Note: It might be a good idea to include the character to count in the message. That would point you to the problem.) – M Oehm May 14 '17 at 18:36
  • @MOehm You are Right .. Brilliant explanation. – Ibrahim Yamani May 14 '17 at 18:40

4 Answers4

5

First, you should have tried debugging your code. If you would have done it, you would have seen that the letter you thought L holds is not what L actually holds.

Second, your problem is simple, L is not getting the letter you enter because of the enter from the string before is stuck in the scanf buffer... use scanf (" %c") [with preceeding whitespace] to resolve.

As mentioned in other answers, there are other solutions like the unrecommended fflush(). An alternative that is not considered harmful is getchar() between the scanf("%s") and the scanf("%c"). That will give you the same effect as using scanf(" %c");

The reason that all of these methods work is because they all consume the last char (which is, in your case the \n) stuck in the buffer, and thus allowing the %c to consume the char you actually intend to read

CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
3

Reason of problem :

scanf("%c",&l) //Here %c takes enter key of scanf("%s",s);;

So, there are mainly 2 solution to your problem:

Sol. 1 => scanf(" %c",&l) //use whitespace before %c

Sol. 2 => Use fflush(stdin) that flushes the output buffer of a stream.

int main()
{

char s[100],l;
printf("Enter A String:\n");
scanf("%s",s);
printf("Enter A Letter:\n");
fflush(stdin);                       //here fflush(stdin) used to flushes the output buffer.
scanf("%c",&l);
l = getchar();
......
......
}

NOte: Since fflush(stdin) has undefined behavior so, always use priority to Solution 1 , instead of fflush(). :)

Shivam Sharma
  • 1,015
  • 11
  • 19
0

Your function definition is wrong in terms of good code practices.

Instead of

int Occur(char S[100], char L)

You should write it as

int Occur(char S[] , char L)

because otherwise your code would specifically look to accept strings of size not more than 100 chars.

Apart from that as Ilario Pierbattista said its a input buffer problem. The stdin needs to get cleared before taking further input, hence the juggad of putting scanf before a getchar() call would work.

Dipunj
  • 33
  • 1
  • 3
  • 12
  • that is not correct. The problem lies in getting the character from input. Declaration and definition of a function are fine – Fureeish May 14 '17 at 18:39
  • @CIsForCookies the post you mentioned discusses function prototype not the definition. – Dipunj May 14 '17 at 18:56
0

It's an input buffer problem. The char is read by getchar instead of scanf. Doing l = getchar() solves the problem (the call of scanf just before clears the input buffer).

#include <stdio.h>
#include <stdlib.h>

int Occur(char [],char);


int main()
{

char s[100],l;
printf("Enter A String:\n");
scanf("%s",s);
printf("Enter A Letter:\n");
scanf("%c",&l);
l = getchar();

printf("Num Of Occurance is %d ",Occur(s,l));


return 0;
}


int Occur(char S[100],char L){

int i;
int num=0;

for(i=0;S[i]!='\0';i++){

if(S[i]==L)
    num++;
}

return num;

}
Ilario Pierbattista
  • 3,175
  • 2
  • 31
  • 41