NO

Author Topic: scanf line skipped on reiterations of while loop  (Read 10090 times)

Phizzy

  • Guest
scanf line skipped on reiterations of while loop
« on: October 13, 2004, 06:11:32 AM »
Note: I'm in an introduction to programming class, any feedback is appreciated.

I've been able to reproduce a problem in Pelles C wherein an infinite loop occurs in the compiled console program built from a source under the following circumstances:

- A "while" loop is used, or a "do while" loop is used.
- A scanf function is used inside the loop.
- The scanf function returns zero

The loop effectively skips the statement containing the scanf function altogether in repetitions of the loop.

-- (Edit: thereby causing an infinite loop)

I initially thought that the defect only occurs if scanf returns a value to a variable (int) that I assigned... however, this is not always true, even when scanf is compared to a constant, it screws up:

Cases when scanf will faulter:

//the most obvious and common case

int x;
x = scanf("%i",x);

//the most annoying case (since the majority of the class is likely using the following mechanism in an attempt to handle erroneous input)

int x;
int xtype;

xtype=0;
while (xtype==0)
{
     xtype=scanf("%i",x);
}

//the even more annoying part of this case is that using the fflush function to remove erroneous input fails to do the job as in

int x;
int xtype;

xtype=0;
while (xtype==0)
{
     fflush(stdin);
     xtype=scanf("%i",x);
}

Note that the fflush can occur before or after the scanf, it really doesn't descriminate after it enters into the loop.

//the final case and one that took a bit of research for me to do to finally locate on the official gnu site is also quite irritating:

int x;
int xtype;

xtype=0;
do {
fflush(stdin);
} while (scanf("%i",x)==0);

//I haven't tried the following and final case, but I'm pretty sure it doesn't work either. Note that the presence of fflush matters not.

int x;
int xtype;

xtype=0;
while (scanf("%i",x)==0);
{
     fflush(stdin);
}

-- (Edit: The underneath was new)

I suppose this bug is associated with another bug I've verified in Pelles C:

If there are multiple scanf's is a sequence, and data entered is incompatible with one variable due to its type, the data is passed from one scanf downstream to the next--

This is usually preventable with fflush, HOWEVER, fflush does nothing in Pelles.

Thanks,
Ed

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
scanf line skipped on reiterations of while loop
« Reply #1 on: October 13, 2004, 03:16:37 PM »
This is not a bug, but possibly a missing feature.

1. fflush() is only for output streams, not input streams.

Quote from: "ISO C Standard"

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.


2. AFAIK, there is no standard way of flushing the input stream. Different C compilers have different solutions for this. I think the Microsoft compiler will accept fflush(stdin), for example.

I will do something about this, but as I said before, not really a bug.

You should be able to use the following code in the mean time:
Code: [Select]

void flush_stdin(void)
{
    /* Note! Non-standard way - only works for Pelles C */
    stdin->ptr = stdin->getend = stdin->buf;
    stdin->backptr = stdin->backbuf + sizeof(stdin->backbuf);
    stdin->getback = 0;
}


Pelle
/Pelle

Phizzy

  • Guest
K, thanks
« Reply #2 on: October 14, 2004, 03:15:04 AM »
Alrighty, thanks a lot.

When do you think a standard will roll around?

(In a C for Dummies book I bought [2004], the author mentioned fflush(stdin) for windows compilers and fpurge(stdin) for linux compilers. I tried using the fflush(stdin) function(argument) in a different compiler (which worked), and it seems to be a generally agreed upon method as my searches on the internet reveal (google up "gnu scanf fflush gcc" or reasonably similar string)... I get the feeling that the function involved evolved twice; once for windows and once for linux-- whatever the case may be, what does fixing this function entail? Do you have to rewrite a library for Pelles or something more?

If it's just a library, could you tell us what lines to modify?

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
scanf line skipped on reiterations of while loop
« Reply #3 on: October 14, 2004, 01:18:07 PM »
It's not part of the standard from 1999, and I *think* the FAQ for comp.std.c have contained an entry for this longer than that, but I'm not sure. I don't think it has very high priority.

I have added fflush(stdin) to version 2.90. A beta will be uploaded very soon.

Pelle
/Pelle