6

I'm beginner in C. Please dont mind if my question is lame. In this program which i have written, when I use 'for' loop first time , I expect only 3 values is stored in an array but it stores 4 values and in next 'for' loop as expected show 3 values. My Question is why in 1st 'for' loop it takes 4 values instead of 3?

#include<stdio.h>
void main()
{
    int marks[3];
    int i;

    for(i=0;i<3;i++)
    {
        printf("Enter a no\n");
        scanf("%d\n",(marks+i));
    }
    for(i=0;i<3;i++)
    {
        printf("%d\n",*(marks+i));
    }
}
m0skit0
  • 25,268
  • 11
  • 79
  • 127
ranaarjun
  • 245
  • 3
  • 5
  • 12

2 Answers2

11

\n in scanf was the problem

#include<stdio.h>
int main()
{
    int marks[3];
    int i;

    for(i=0;i<3;i++)
    {
        printf("Enter a no\n");
        scanf("%d",(marks+i));
    }

    printf("\nEntered values:\n");
    for(i=0;i<3;i++)
    {
        printf("%d\n",*(marks+i));
    }

    return 0;
}

Reason:

I expect only 3 values is stored in an array but it stores 4 values and in next 'for' loop as expected show 3 values. My Question is why in 1st 'for' loop it takes 4 values instead of 3?

First: No, it only stores 3 number but not 4 numbers in array marks[].

Second: interesting to understand loop runs only for three times for i = 0 to i < 3. The for loop runs according to condition. More interesting code is stuck in scanf() as described below:

Your confusion is why you have to enter four numbers, its not because you loop runs 4 times but its because scanf() function returns only when you enter a non-space char (and after some enter press you inputs a number symbol that is non-space char).

To understand this behavior read manual: int scanf(const char *format, ...);:

A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). This directive matches any amount of white space, including none, in the input.

Because in first for loop's, in scanf() you have included \n in format string, so scanf() returns only if press a number enter (or a non-space key).

 scanf("%d\n",(marks+i));
           ^
           |
            new line char 

What happens?

Suppose input to program is:

23        <--- because of %d 23 stored in marks[0] as i = 0
<enter>   <--- scanf consumes \n, still in first loop
543       <--- scanf returns, and leave 542 unread, 
                               then in next iteration 543 read by scanf in next iteration
<enter> 
193
<enter>  <--- scanf consumes \n, still in 3rd loop
<enter>  <--- scanf consumes \n, still in 3rd loop
123      <--- remain unread in input stream 
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
Sanyam Goel
  • 2,138
  • 22
  • 40
  • thanx DX but when i used \n after %d in scanf, it takes 2 values first time when value of i is 0 but when value of i becomes 1 and 2 it takes only 1, why this happens? – ranaarjun Jul 24 '13 at 10:24
  • 1
    please go through this http://answers.yahoo.com/question/index?qid=20110801122000AA07FO8 hope this gives you the exact reason – Sanyam Goel Jul 24 '13 at 10:26
  • 1
    @GrijeshChauhan sure it will be helpful for all :) Please do – Sanyam Goel Jul 24 '13 at 10:43
  • 4
    read from [`int scanf ( const char * format, ... );`](http://www.cplusplus.com/reference/cstdio/scanf/) in **Parameters**/ if format string is a **Whitespace character:** itd return *`A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).`* So when @ranaarjun use `\n` in scanf it always wait to read a `\n` even after last number enter, and because `\n` can consume any number of `\n` as I quote to until **OP** don't enter a non-while char (he actually entered number then) scanf don't leave reading from input-stream – Grijesh Chauhan Jul 24 '13 at 10:54
  • @GrijeshChauhan nice and healthy explanation :) thanks – Sanyam Goel Jul 24 '13 at 10:56
  • @GrijeshChauhan Yes it will be good if you put the same explanation in a new answer since you have explained it better you should be getting the rps for the explanation – Sanyam Goel Jul 24 '13 at 11:03
  • @SanyamGoel always remember that fflush(stdin) is an undefined behavior ..... we all are here to learn :) – 0decimal0 Jul 24 '13 at 13:12
  • Yes this explains in the most easy way thanks :) – Sanyam Goel Jul 29 '13 at 12:24
  • @GrijeshChauhan; Nice explanation. I like specially last part of this answer. – haccks Aug 05 '13 at 19:31
  • @haccks Thanks! did you read this [Scanf won't execute for second time](http://stackoverflow.com/questions/17827603/scanf-wont-execute-for-second-time?lq=1) I explained scanf in much depth – Grijesh Chauhan Aug 06 '13 at 06:23
  • @haccks , SanyamGoel, PHIfounder : To understand scanf and printf One should read [C Printf and Scanf Reference](http://wpollock.com/CPlus/PrintfRef.htm) – Grijesh Chauhan Aug 06 '13 at 06:38
0

remove \n and i can be created in the if statement as for (int i = 0; i < 3; i++) {}

Provessor
  • 11
  • 2