0

I'm new in programming and now I'm trying to learn how to use EOF.

I want to insert a string from keyboard and count the letters. For example

Give string: abcd
I have 1a , 1b , 1c ,1d.

My code so far is

while(scanf("%s",s)!=EOF){

    if(s[i]=='a')
        counta++;
    if(s[i]=='b')
        countb++;

    //and so on

    i++;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
cmd
  • 1
  • Note that using `counta` etc is a minor (but very verbose) disaster in the making. You should use an array of integers, indexed by the `(unsigned char)` value of `s[i]` (when you have a second loop as shown in [Woodrow Barlow](http://stackoverflow.com/users/3961271/woodrow-barlow)'s [answer](http://stackoverflow.com/a/25557942/15168), or [Danke Xie](http://stackoverflow.com/users/382871/danke-xie)'s [answer](http://stackoverflow.com/a/25557729/15168)). – Jonathan Leffler Aug 28 '14 at 21:06

2 Answers2

1

scanf("%s", s) returns EOF when you reach the end of the standard input (stdin). You need another loop to iterate over the characters in each string:

while(scanf("%s",s)!=EOF) {
   for (int i = 0; s[i]; i++) {
       if(s[i]=='a')
           counta++;
       else if(s[i]=='b')
           countb++;
       //and so on
   }
}
Danke Xie
  • 1,757
  • 17
  • 13
1

Your terminal operates in something called "canonical mode" (also called "line-buffered mode"). That means that stdin is actually buffered -- your program isn't aware that anything is on stdin until the user presses enter (this is the trigger for canonical terminals). This is a more efficient way of handling input than non-buffered input. Because of this, when using functions like scanf, you won't get any data from stdin until you press enter, at which point you'll get the entire string.

while(scanf("%s",s) != EOF) // get a line of input from stdin until input is finished
{
  int i;
  for(i = 0; s[i] != '\0'; i++) // scan each character of that line
  {
    // check the value of s[i] and do some action
  }
}

Note that this will keep going until an EOF character is sent instead of a line of text. That can happen in two scenarios: if input is being piped from a file, it happens at end of file, and if input is coming from the keyboard at the terminal, it happens when you send an interrupt (ctrl+C).

Woodrow Barlow
  • 8,477
  • 3
  • 48
  • 86
  • You might do better with a `for` loop, particularly as you don't really want to increment `i` until the end of the loop. The alternative would be `while ((c = s[i++]) != '\0')` and use `c` in the loop body instead of `s[i]`. The type of `c` should probably be `unsigned char` (just in case plain `char` is a signed quantity). – Jonathan Leffler Aug 28 '14 at 21:08
  • Is it not true that the `i++` doesn't happen until the end of each loop iteration (C side-effects)? – Woodrow Barlow Aug 29 '14 at 13:32
  • The side effects are complete by the end of the statement which in this case is the condition portion of the `while` loop. – Jonathan Leffler Aug 29 '14 at 13:36