Sunday, October 30, 2022

[FIXED] How can I get input integers from user until he press enter by using eof?

Issue

we start coding C and I cant solve my h.w because I dont know how to get input from the user (integers) until he press enter like 20 30 10 40 and after that the while done by using eof. here is part of the code that doesnt work,

printf("Students, please enter heights!\n");
   while((scanf("%d",&height))!=EOF)
    {
        if(height>0)
        {
            avg_girls=avg_girls+height;
            counter_girls++;
        }

        else
        {
            avg_boys=avg_boys+height;
            counter_boys++;
        }  
    }

I getting into infinity loop thanks you very much.


Solution

While a better way to accomplish reading an unknown number of integers from a line would be to read the entire line into a buffer of sufficient size and then step through the buffer using strtol (utilizing its endptr parameter to update your position in the buffer to 1-character past the last value converted), you can use scanf and accomplish the same thing.

One approach for using scanf to read multiple integers from a line of input is simply to read each character and confirm it is not the '\n' character or EOF. If the character isn't a digit (or a '-' sign preceding a digit - thanks Ajay Brahmakshatriya), then just go get the next character. If the character is a digit, put it back in stdin with ungetc and then call scanf and validate the conversion before updating either girls or boys average based on the sign of the input.

You could do something like the following:

    int height;

    fputs ("enter heights: ", stdout);

    while ((height = getchar()) != '\n' && height != EOF) {
        /* if not '-' and not digit, go read next char */
        if (height != '-' && !isdigit (height))
            continue;
        ungetc (height, stdin);     /* was digit, put it back in stdin */
        if (scanf ("%d", &height) == 1) {   /* now read with scanf */
            if (height > 0) {       /* postive val, add to girls */
                avg_girls += height;
                counter_girls++;
            }
            else {                  /* negative val, add to boys */
                avg_boys += height;
                counter_boys++;
            }
        }
    }

The isspace() macro is provided by the ctype.h header. If you cannot include other headers, then simply check whether height is a digit manually, e.g.

    if (height != '-' && (height < '0' || '9' < height))
        continue;

(remember you are reading characters with getchar(), so make the comparison against the ASCII characters for '0' and '9')

Another alternative is to read the entire line of input into a buffer and then repeatedly call sscanf converting integers as you work through the buffer additionally utilizing the "%n" specifier to report the number of characters consumed by the call to sscanf. (e.g. using "%d%n" and providing a pointer to int to hold the value provided by "%n") You can then keep a running total of the offset from the beginning of the buffer to add to your pointer to position sscanf for its next read.

Either way is fine, but reading a line-at-a-time presents many fewer pitfalls for the new C programmer to navigate than attempting to work with scanf and stdin itself.



Answered By - David C. Rankin
Answer Checked By - Senaida (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.