EOF-unwanted loop!!!

The problem is that I want the first loop to be countered but the second with the sentinel value 'EOF' I wrote the program like this. However, when I entered Ctrl^Z nothing happened on the other hand with Ctrl^D unwanted infinite loop appeared. WHY? and HOW TO SOLVE THE PROBLEM? (OP=windows, used program codeblocks)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  #include <stdio.h>
#include <stdlib.h>

int main(){

    float product1,product2,product3,product4,product5;         // calculator for products' prices
    int product,quantity,day;                                   // product is a sentinel value
    float sum=0;
    float price1=2.98,
          price2=4.50,
          price3=9.98,
          price4=4.49,
          price5=6.87;

    printf("%s%20s\n","PRODUCT NUMBER","RETAIL PRICE");
    printf("1%25.2f\n",price1);
    printf("2%25.2f\n",price2);
    printf("3%25.2f\n",price3);
    printf("4%25.2f\n",price4);
    printf("5%25.2f",price5);

    for(day=1;day<=7;day++){

        product1=product2=product3=product4=product5=1;
        product=0;

        printf("\n\n*********** Day %d ***********\n\n",day);

        while(product!=EOF){

            printf("Enter product number(EOF to exit): ");
            scanf("%d",&product);

            if(product!=EOF){
                printf("Enter quantity sold for one day: ");
                scanf("%d",&quantity);

                switch(product){

                case 1:
                    product1=1.*quantity*price1;
                    break;
                case 2:
                    product2=1.*quantity*price2;
                    break;
                case 3:
                    product3=1.*quantity*price3;
                    break;
                case 4:
                    product4=1.*quantity*price4;
                    break;
                case 5:
                    product5=1.*quantity*price5;
                    break;
                }
            }
        }
        sum+=(product1+product2+product3+product4+product5);
    }
    printf("Total retail for last week: %.2f",sum);

    return 0;
}


the thing I wish is that with EOF I want the inner loop to terminate, the counter of the outer loop to count +1 and the inner loop to execute till EOF is entered. and repeat this iteratively until the 'day' goes to 7.
Last edited on
Have you tried CTRL+Z instead of CTRL+D on Windows? For details, see here:
https://stackoverflow.com/a/977063
Last edited on
Because it should be
1
2
3
4
5
6
7
8
9
int r = scanf("%d",&product);
if ( r == 1 ) {
  // success
} else if ( r == 0 ) {
  // garbage was typed in, which you need to get rid of.
  // usually by reading characters up to the next newline
} else if ( r == EOF ) {
  // User has had enough, bail out
}

RETURN VALUE
On success, these functions return the number of input items successfully matched and assigned; this can be fewer than provided for, or even zero, in the event of an early matching failure.

The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case
the error indicator for the stream (see ferror(3)) is set, and errno is set to indicate the error.

kigar64551

I tried it didn't work, acted like operator 'continue' kind of that doesn't affect anything
Last edited on
salem c

I didn't get the point what exactly you mean
I didn't get the point what exactly you mean

You have to check the return value of scanf(). In your code, the return value is not regarded at all 😏

scanf() will only store values to the given pointer(s) in the argument list (in your case &product), if the user input is valid.

The return value tells you how many items were successfully filled – in your case this will be 0 or 1, because you only have one item.

Therefore: If scanf() returns anything other than 1, then the value stored in product must be considered undefinednot EOF.

scanf() returns the special value EOF, if the end of the stream was reached before the first item (e.g. product) was successfully filled.

(Never the EOF value would be stored in product. Well, except if the user successfully enters "-1", which coincides with EOF)
Last edited on
Study and try.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ cat foo.c
#include <stdio.h>
int main ( ) {
    int product;
    int r = scanf("%d",&product);
    if ( r == 1 ) {
        printf("Yes, you typed in %d\n", product);
    } else if ( r == 0 ) {
        printf("No, I don't understand\n");
    } else if ( r == EOF ) {
        printf("Well if you feel that way, bye!\n");
    }
    return 0;
}
$ gcc foo.c
$ ./a.out 
123
Yes, you typed in 123
$ ./a.out 
123456789012345678901234567890
Yes, you typed in -1
$ ./a.out 
hello world
No, I don't understand
$ ./a.out 
Well if you feel that way, bye!
$  


The second test shows the other deficiency of scanf functions. They can't be relied upon to detect overflow. My version will set errno, but historically, the result was just some modulo 2n rounding of the result (YMMV).

On the last run, just press CTRL-D or CTRL-Z - whatever your OS convention for signalling EOF is.
Line 32, 36: scanf is unsafe. It has been replaced by scanf_s.
scanf_s has been standard since C11.
https://en.cppreference.com/w/c/io/fscanf

You really should learn to use arrays.
Keep in mind that arrays are zero based.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>
#include <stdlib.h>

const int MAX_PRODUCTS = 5;  /* Edit: was contexpr */

int main() 
{   
    float product[MAX_PRODUCTS] {};
    int quantity, day, prod;                                   
    float sum = 0;
    float price[MAX_PRODUCTS] =
        {   2.98,
            4.50,
            9.98,
            4.49,
            6.87
        };
    
    printf("%s%20s\n", "PRODUCT NUMBER", "RETAIL PRICE");
    for (int i=0; i<MAX_PRODUCTS; i++)
        printf("%d %25.2f\n", i+1, price[i]);    
    for (day = 1; day <= 7; day++) 
    {
        printf("\n\n*********** Day %d ***********\n\n", day);
        do
        {   
            printf("Enter product number(0 to exit): ");
            scanf_s("%d", &prod);
            if (prod == 0)
                break;  
            printf("Enter quantity sold for one day: ");
            scanf_s("%d", &quantity);
            product[day - 1] = quantity * price[prod - 1];                           
        }
        while(prod > 0);
        for (int i = 0; i < MAX_PRODUCTS; i++)
            sum += product[i];  
    }
    printf("Total retail for last week: %.2f", sum);
    return 0;
}

Last edited on
Does c now support constexpr?

Line 32, 36: scanf is unsafe. It has been replaced by scanf_s.


Not for reading an int s used here - only for %c, %s and %[

In any case, in the code above the return value from scanf_s isn't used...
Last edited on
thank you all for helping guys
seeplus wrote:
Does c now support constexpr?

I can't find any reference to constexpr being in the C standard, although my compiler supports it.
 
const int NUM_PRODUCTS = 5;

Would have been a better choice.

seeplus wrote:
Not for reading an int s used here - only for %c, %s and %[

That may be true, but some compilers (MSC) flag all use of scanf as unsafe.


Would have been a better choice.


In c for the purpose of array size, const int isn't considered a constant value (unlike in C++). You need:

 
#define NUM_PRODUCTS 5 


but some compilers (MSC) flag all use of scanf as unsafe.


You can use:
 
#define _CRT_SECURE_NO_WARNINGS 


to suppress these warnings.
Topic archived. No new replies allowed.