473,785 Members | 3,388 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Discarding unread data after scanf()

Is this a good way to discard unread data after scanf()?

while (getchar() != '\n')
;

According to the FAQ scanf always leaves the trailing newline on the input
stream, so there's no risk of discarding any more than needed. (In the best
case, when scanf() correctly works and the user hasn't input spurious data
beside those required in the control string, the loop will only iterate
once.)

(The only problem is if for some reason stdin is a file and it ends. But I
could well use drastic solutions such as
assert(!feof(st din) && !ferror(stdin)) ;
as the loop body, since if a program designed to be interactive reads from a
file which ends we can't do anything better than abort execution.)

--
#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;
}
Mar 25 '07 #1
8 5171
Army1987 wrote:
>
Is this a good way to discard unread data after scanf()?
A call to fscanf with stdin as the first argument,
is just like a call to scanf.

/* BEGIN fscanf_input.c */
/*
** There are only three different values
** that can be assigned to rc
** from the fscanf calls in this program.
** They are:
** EOF
** 0
** 1
** If rc equals EOF, then the end of file was reached,
** or there is some input problem;
** ferror and feof can be used to distinguish which.
** If rc equals 0, then an empty line was entered
** and the array contains garbage values.
** If rc equals 1, then there is a string in the array.
** Up to LENGTH number of characters are read
** from a line of a text stream
** and written to a string in an array.
** The newline character in the text line is replaced
** by a null character in the array.
** If the line is longer than LENGTH,
** then the extra characters are discarded.
*/
#include <stdio.h>

#define LENGTH 40
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
int rc;
char array[LENGTH + 1];

puts("The LENGTH macro is " xstr(LENGTH) ".");
do {
fputs("Enter any line of text to continue,\n"
"or just hit the Enter key to quit:", stdout);
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
if (rc == 0) {
array[0] = '\0';
}
if (rc == EOF) {
puts("rc equals EOF");
} else {
printf("rc is %d. Your string is:%s\n\n", rc, array);
}
} while (rc == 1);
return 0;
}

/* END fscanf_input.c */
--
pete
Mar 25 '07 #2

"pete" <pf*****@mindsp ring.comha scritto nel messaggio
news:46******** ***@mindspring. com...
Army1987 wrote:
>>
Is this a good way to discard unread data after scanf()?

A call to fscanf with stdin as the first argument,
is just like a call to scanf.
I know that. But that isn't what I was asking.

#include <stdio.h>
int input(const char *prompt)
{
int flag, result;
puts(prompt);
flag = scanf("%d", &result);
while (getchar() != '\n')
;
while (flag < 1) {
puts("Please enter an integer value");
flag = scanf("%d", &result);
while (getchar() != '\n')
;
}
return result;
}

Is this ok (supposing stdin is interactive)?
Mar 25 '07 #3

"Army1987" <pl********@for .itha scritto nel messaggio
news:eu******** **@tdi.cu.mi.it ...
#include <stdio.h>
int input(const char *prompt)
{
int flag, result;
puts(prompt);
fflush(stdout); /* forgot that... */
flag = scanf("%d", &result);
while (getchar() != '\n')
;
while (flag < 1) {
puts("Please enter an integer value");
fflush(stdout);
flag = scanf("%d", &result);
while (getchar() != '\n')
;
}
return result;
}

Is this ok (supposing stdin is interactive)?

Mar 25 '07 #4
Army1987 wrote:
puts(prompt);
fflush(stdout); /* forgot that... */
I don't think that fflush(stdout) is required
after a newline character is output.
puts always outputs a complete
line of text with newline character at the end.
I think of puts as creating a line of text from a string.

In case you don't know, a "line in a text stream"
is somewhat analagous to a "string in memory",
with a "line" being terminated by a newline character
while a "string" is terminated by a null character.

I misread your intial post as "Is there..."
when you has actually written "Is this..."

I will take another look at your code.

--
pete
Mar 25 '07 #5
Army1987 wrote:
>
Is this a good way to discard unread data after scanf()?

while (getchar() != '\n')
;
Your while loop will prevent endless looping from alpha input
while scanfing for int input.

/* BEGIN new_1.c output */

Please enter an integer value
ksdhfgkdashfkfr hwe
Please enter an integer value
wekjwerhiweuq
Please enter an integer value
wejuf
Please enter an integer value
wekjh
Please enter an integer value
ds
Please enter an integer value
42

The result is 42

/* END new_1.c output */

/* BEGIN new_2.c output */

Please enter an integer value
a
Please enter an integer value
Please enter an integer value
Please enter an integer value
Please enter an integer value
Please enter an integer value
Please enter an integer value ... and so on and so forth.

/* BEGIN new_1.c */

#include <stdio.h>

int input(const char *prompt);

int main(void)
{
puts("/* BEGIN new_1.c output */\n");
printf("\nThe result is %d\n",
input("Please enter an integer value"));
puts("\n/* END new_1.c output */");
return 0;
}

int input(const char *prompt)
{
int flag, result;

puts(prompt);
flag = scanf("%d", &result);
while (getchar() != '\n') {
;
}
while (flag < 1) {
puts("Please enter an integer value");
flag = scanf("%d", &result);
while (getchar() != '\n') {
;
}
}
return result;
}

/* END new_1.c */

/* BEGIN new_2.c */

#include <stdio.h>

int input(const char *prompt);

int main(void)
{
puts("/* BEGIN new_2.c output */\n");
printf("\nThe result is %d\n",
input("Please enter an integer value"));
puts("\n/* END new_2.c output */");
return 0;
}

int input(const char *prompt)
{
int flag, result;

puts(prompt);
flag = scanf("%d", &result);
while (flag < 1) {
puts("Please enter an integer value");
flag = scanf("%d", &result);
}
return result;
}

/* END new_2.c */

--
pete
Mar 25 '07 #6
On Sun, 25 Mar 2007 12:54:19 +0200, "Army1987" <pl********@for .it>
wrote:
>Is this a good way to discard unread data after scanf()?

while (getchar() != '\n')
;

According to the FAQ scanf always leaves the trailing newline on the input
stream, so there's no risk of discarding any more than needed. (In the best
case, when scanf() correctly works and the user hasn't input spurious data
beside those required in the control string, the loop will only iterate
once.)

(The only problem is if for some reason stdin is a file and it ends. But I
could well use drastic solutions such as
assert(!feof(st din) && !ferror(stdin)) ;
as the loop body, since if a program designed to be interactive reads from a
file which ends we can't do anything better than abort execution.)
If you are worried about end of file as well as end of line you can
use something like
{int x; while (((x = getchar()) != '\n' ) && x != EOF) /* */;}
Remove del for email
Mar 25 '07 #7
"Army1987" <pl********@for .itwrites:
Is this a good way to discard unread data after scanf()?

while (getchar() != '\n')
;
No.
According to the FAQ scanf always leaves the trailing newline on the input
stream, so there's no risk of discarding any more than needed. (In the best
case, when scanf() correctly works and the user hasn't input spurious data
beside those required in the control string, the loop will only iterate
once.)
What scanf leaves on the input stream depends on the format string.
With the right format string, it can consume the trailing newline.

In a later followup, you said you're using a "%d" format. In that
case, *if* you're going to use scanf() for input, then the above loop
with the addition of a check for EOF (see below) is reasonable,
assuming you want to accept just one integer value per input line.

But scanf() is usually not the best way to handle interactive input.
A better approach is to use fgets() to read an entire line at a time,
then use sscanf() to parse the line.

But even that has problems. If either scanf() or sscanf() with a "%d"
format attempts to read a number that won't fit in type int, the
behavior is undefined; there's no way to detect the error once it's
happened. If that's a concern, you might consider using strtol(),
which does detect and report overflow and underflow.

fgets() can also have problems with very long lines. I *think* this
is covered in the FAQ.
(The only problem is if for some reason stdin is a file and it ends. But I
could well use drastic solutions such as
assert(!feof(st din) && !ferror(stdin)) ;
as the loop body, since if a program designed to be interactive reads from a
file which ends we can't do anything better than abort execution.)
By "stdin is a file", I assume you mean that the program is reading
from a disk file rather than from, say, a keyboard. But you can
easily reach an end-of-file condition when reading from a keyboard.
<OT>On Unix-like systems, this is usually caused by the user typing
control-D; on DOS or Windows systems, it's usually control-Z.</OT You
should handle that case cleanly.

You can do much better than just aborting execution with a message
like:

assertion "!feof(stdi n) && !ferror(stdin)" failed: file "c.c", line 6

You can test for end-of-file (preferably by comparing the result of
getchar() to EOF, not by calling feof() or ferror()), and you can
*gracefully* terminate the program. Quite often, reaching end-of-file
is the normal way for a program to terminate, simply because it has no
more work to do. In an interactive program that's expecting more
input, you can at least terminate with an error message that's going
to be meaningful to the user.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 25 '07 #8
Groovy hepcat Army1987 was jivin' on Sun, 25 Mar 2007 12:54:19 +0200
in comp.lang.c.
Discarding unread data after scanf()'s a cool scene! Dig it!
>Is this a good way to discard unread data after scanf()?

while (getchar() != '\n')
;
No, not really. You need to test for EOF.
>According to the FAQ scanf always leaves the trailing newline on the input
stream, so there's no risk of discarding any more than needed. (In the best
case, when scanf() correctly works and the user hasn't input spurious data
beside those required in the control string, the loop will only iterate
once.)

(The only problem is if for some reason stdin is a file and it ends.
Or it's an interactive device, and the user presses whatever key
combination (or takes whatever course of action) indicates an end of
file condition on the device. Or it's a punched tape reader, and the
tape breaks. Or it's an electroencephal ograph, and the person whose
noggin it's wired up to has fallen asleep. Or it's any kind of device
ever invented by the mind and made by the hand of mankind, and
something goes wrong with it.
But I
could well use drastic solutions such as
assert(!feof(st din) && !ferror(stdin)) ;
Indeed that is a drastic solution. Don't do that. That's no way to
use assert(). It's for catching programming errors, not input errors.
When NDEBUG is defined, every use of assert() becomes a no-op. In this
situation you lose all your input error checking. And you don't want
to lose that.
Besides, there are better ways of determining whether there's a file
stream problem. Use the return value of the input function you're
using. All the file input functions return some indication of whether
or not they failed or tryed to read beyond the end of the file. For
example, getchar() returns EOF on failure or end of file. You can then
use ferror() or feof() to determine which of those two conditions
occurred.
>as the loop body, since if a program designed to be interactive reads from a
file which ends we can't do anything better than abort execution.)
I recently posted a simple function that could do what you want. But
since you lurked here for some time before posting, as all good Usenet
denizens do, as they should, you must know that. I'm sure it just
slipped your mind. So I will refresh your memory. Here is the
function, slightly modified to return EOF on error or end of file:

#include <stdio.h>

int skip2nl(FILE *fp)
{
int c;

while(EOF != (c = fgetc(fp)) && '\n' != c)
;

return c;
}

You could use this function something like this:

int main(void)
{
int status;

puts("Enter some stuff on stdin, "
"and I will attempt to skip it...\n");

status = skip2nl(stdin);
if(EOF == status)
{
if(ferror(stdin ))
{
puts("File error on stdin.");
}
else
{
puts("End of file on stdin.");
}
}
else
{
puts("Newline read from stdin.");
}

return 0;
}

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technicall y correct" English; but since when was rock & roll "technicall y correct"?
Mar 28 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
3797
by: CAFxX | last post by:
i'm writing a program that executes some calculations on a bitmap loaded in memory. these calculation ends up with pixel wth values far over 255, but i need them to be between 0 and 255 since i got to write them in a bmp file (in which RGB values are limited to 8 bits per channel). so i need to have them scaled down. first of all i find the highest and lowest of those values:(keep in mind that max, min, bmp, ptr are ulong and w, h are...
2
1351
by: Cincin | last post by:
We were building this forum application and we stumble on how to identify unread post. One thing would be to keep in the database what an user have seen but it doesn't seem doable because of the possible large number of users/posts and also anonymous users. Do you have an idea on how this can be done, what options do I have to do this? Thanks
1
2222
by: Kondapanaidu | last post by:
Hi, I am using C#.NET2.0, My Outlook Inbox is having some mails. My system Configured with Outlook, I need to capture the Unread mail subject line. How to capture the subject line from the unread mail.
2
1990
by: a | last post by:
keep a list of read and unread items hi guys i m building an rss reader and i want you suggestions for datastructure for keeping read and unread list for each use i m assuming it will be very sparse thanks
1
7064
by: PhilD | last post by:
My C#.NET console app checks a public folder every 24 hours for incoming emails. For each unread email in the folder, it copies any attachments to the network, then loads the contents of these files into a SQL Server database, and marks the email as read. My problem is that in the loop that checks for all the Unread emails in the folder, as I spin through the loop, the number of unread items is being reset for every iteration. So...
14
13814
by: main() | last post by:
I know this is the problem that most newbies get into. #include<stdio.h> int main(void) { char a; scanf("%c",&a); /*1st scanf */ printf("%c\n",a); scanf("%c",&a); /*2nd scanf*/ printf("%c\n",a);
2
6555
by: subramanian100in | last post by:
Consider the following program named as x.c #include <stdlib.h> #include <stdio.h> int main(void) { unsigned int u; char str;
30
1947
by: George | last post by:
1 0001000000000000001 2 0001000000000000001 3 10000011001000000000000001 4 10000011001000000000000001 5 10000011001000000000000001 6 10000011001000000000000001 7 10000011001000000000000001 8 10000011001000000000000001 9 10000011001000000000000001 10 10000011001000000000000001
17
19236
by: vishal1082 | last post by:
i wanna get number of unread mails from mail servers, like gmail, yahoo, msn, aim and any other email server which user gives but the problem is - i dont know HOW (lol) i tried this DLL: http://www.lesnikowski.com/mail/faq.aspx but in its faq it says this: That is not possible with POP3 protocol. There is no way to mark on the server which messages were received by client application. You have to mark which messages have been read by...
0
9643
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9480
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10319
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10087
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9947
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8971
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7496
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6737
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
2
3645
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.