473,406 Members | 2,356 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

checking and verifying input line in a C program

In a C program I am required to enter three numbers (integers) e.g. 256
7 5 on execution of the program.

C:\> 256 7 5

There should be spaces between the three numbers and on pressing
"enter", further processing is done. The problem requires me to check
whether three numbers have actually been entered in the input line and
to warn if less or more numbers have been entered.

The actual program is required to do something else. But I'm stuck at
this initial input verification. If I use 3 variables x,y & z to store
these numbers and use scanf() e.g. scanf("%d%d%d",&x,&y,&z) then the
problem remains that the input process is not interactive. If excess
arguments are given, anything beyond the third argument will be
discarded by scanf(). If someone gives less than 3 arguments and press
"enter", the cursor goes to the next line and waits.

I guess, the problem requies me to make this process more interactive.
It will warn if less than 3 or more than 3 numbers are keyed by the
user in the input line. Evidently scanf() cannot handle it.

How to implement it in the least complicated manner?

Jan 29 '06 #1
7 2618
Hulo wrote:
In a C program I am required to enter three numbers (integers) e.g.
256 7 5 on execution of the program.

C:\> 256 7 5

There should be spaces between the three numbers and on pressing
"enter", further processing is done. The problem requires me to check
whether three numbers have actually been entered in the input line and
to warn if less or more numbers have been entered.
if you search this newsgroup, I believe that recently there was a thread
discussing somewhat similar problems (look for strtok()). See also my
comments below.

The actual program is required to do something else. But I'm stuck at
this initial input verification. If I use 3 variables x,y & z to store
these numbers and use scanf() e.g. scanf("%d%d%d",&x,&y,&z) then the
problem remains that the input process is not interactive. If excess
arguments are given, anything beyond the third argument will be
discarded by scanf(). If someone gives less than 3 arguments and press
"enter", the cursor goes to the next line and waits.
Do not use scanf() (for detailed discussion of why, search this
newsgroup). If you have to, use fgets()/sscanf() combination. Look them
up in your manual/textbook.

I guess, the problem requies me to make this process more interactive.
It will warn if less than 3 or more than 3 numbers are keyed by the
user in the input line. Evidently scanf() cannot handle it.

How to implement it in the least complicated manner?


You could also try to get your line with fgets() (again, do not use
gets() -- it's dangerous as it can create buffer overflows, see
elsewhere in this newsgroup for detailed discussion), and process it
with strtok(). Look it up in your manual/textbook, and there was also a
thread here recently which discussed strtok() in some detail.

Once you read up on these, give it a go by writing a simple program. If
you get specific problems in your code, do come back here and ask.

Cheers

Vladimir

Jan 29 '06 #2

Hulo wrote:
In a C program I am required to enter three numbers (integers) e.g. 256
7 5 on execution of the program.

C:\> 256 7 5

There should be spaces between the three numbers and on pressing
"enter", further processing is done. The problem requires me to check
whether three numbers have actually been entered in the input line and
to warn if less or more numbers have been entered.

The actual program is required to do something else. But I'm stuck at
this initial input verification. If I use 3 variables x,y & z to store
these numbers and use scanf() e.g. scanf("%d%d%d",&x,&y,&z) then the
problem remains that the input process is not interactive. If excess
arguments are given, anything beyond the third argument will be
discarded by scanf(). If someone gives less than 3 arguments and press
"enter", the cursor goes to the next line and waits.

I guess, the problem requies me to make this process more interactive.
It will warn if less than 3 or more than 3 numbers are keyed by the
user in the input line. Evidently scanf() cannot handle it.

How to implement it in the least complicated manner?


use fgets() to read the whole line, then sscanf() to parse the line.
sscanf()
indicates how many items it read.
--
Nick Keighley

Jan 29 '06 #3
On 29 Jan 2006 04:36:06 -0800, in comp.lang.c , "Hulo"
<sa*************@gmail.com> wrote:
The actual program is required to do something else. But I'm stuck at
this initial input verification. If I use 3 variables x,y & z to store
these numbers and use scanf() e.g. scanf("%d%d%d",&x,&y,&z) then the
problem remains that the input process is not interactive. If excess
arguments are given, anything beyond the third argument will be
discarded by scanf(). If someone gives less than 3 arguments and press
"enter", the cursor goes to the next line and waits.


fgets, then sscanf, then handle too many/ not enough data points.
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Jan 29 '06 #4
Hulo wrote:
In a C program I am required to enter three numbers (integers) e.g. 256
7 5 on execution of the program.

C:\> 256 7 5

There should be spaces between the three numbers and on pressing
"enter", further processing is done. The problem requires me to check
whether three numbers have actually been entered in the input line and
to warn if less or more numbers have been entered.


You've hit what is a surprisingly non trivial thing to do in C. A truly
robust bullet proof program will allow the user to do some things like
entering 00000000000000000000000000000000000000012,
potentially exhausting any fixed with input buffer. The fgets/sscanf
combination can fail because of that and sscanf's %d invokes
undefined behaviour if it receives an integer which is outside the
range of int.

One way is to write a routine that excepts an arbitrary large
input line by dynamically allocating space for it (samples have been
posted to clc on numerous occasions), and then parse that input
using strtol (making use of the 'end' pointer).

If you're willing to flag multiple leading zeros as an error, then you
can fix your buffer to a compile time fixed limit. The following is
not checked, but is a rough guide...

#define BIG_ENOUGH_FOR_INT \
( (int) (sizeof(int) * CHAR_BIT + 11) / 3) )

const char format[100 + BIG_ENOUGH_FOR_INT*3];
char n1[BIG_ENOUGH_FOR_INT];
char n2[BIG_ENOUGH_FOR_INT];
char n3[BIG_ENOUGH_FOR_INT];
char c;
int r;
long l1, l2, l3;

sprintf(format, "%%%d[0123456789]"
"%%*[ \t]%%%d[0123456789]"
"%%*[ \t]%%%d[0123456789]"
"%%c",
BIG_ENOUGH_FOR_INT,
BIG_ENOUGH_FOR_INT,
BIG_ENOUGH_FOR_INT);

scanf("%*[ \t]"); /* ignore leading whitespace */
r = scanf(format, n1, n2, n3, &c);
if (r == 3 || r == 4 && c == '\n')
{
errno = 0;
l1 = strtol(n1, NULL, 10);
l2 = strtol(n2, NULL, 10);
l3 = strtol(n3, NULL, 10);
... further validations...
}

Another alternative is to write your own routine to parse input that
reads a
single integer and does the conversion to int (avoiding overflow),
without
ignoring leading whitespace.

--
Peter

Jan 30 '06 #5
Peter Nilsson wrote:
Hulo wrote:
In a C program I am required to enter three numbers (integers) e.g. 256
7 5 on execution of the program.

C:\> 256 7 5

There should be spaces between the three numbers and on pressing
"enter", further processing is done. The problem requires me to check
whether three numbers have actually been entered in the input line and
to warn if less or more numbers have been entered.

You've hit what is a surprisingly non trivial thing to do in C. A truly
robust bullet proof program will allow the user to do some things like
entering 00000000000000000000000000000000000000012,
potentially exhausting any fixed with input buffer. The fgets/sscanf
combination can fail because of that and sscanf's %d invokes
undefined behaviour if it receives an integer which is outside the
range of int.

One way is to write a routine that excepts an arbitrary large
input line by dynamically allocating space for it (samples have been
posted to clc on numerous occasions), and then parse that input
using strtol (making use of the 'end' pointer).

If you're willing to flag multiple leading zeros as an error, then you
can fix your buffer to a compile time fixed limit. The following is
not checked, but is a rough guide...

#define BIG_ENOUGH_FOR_INT \
( (int) (sizeof(int) * CHAR_BIT + 11) / 3) ) ( (int) (sizeof(int) * CHAR_BIT + 5) / 3) )
is enough for signed, isn't it?
I wonder why you are using two more places...
const char format[100 + BIG_ENOUGH_FOR_INT*3];
char n1[BIG_ENOUGH_FOR_INT];
char n2[BIG_ENOUGH_FOR_INT];
char n3[BIG_ENOUGH_FOR_INT];


Xavier
Jan 31 '06 #6
Peter Nilsson wrote:
.... snip ...
You've hit what is a surprisingly non trivial thing to do in C. A
truly robust bullet proof program will allow the user to do some
things like entering 00000000000000000000000000000000000000012,
potentially exhausting any fixed with input buffer. The fgets/sscanf
combination can fail because of that and sscanf's %d invokes
undefined behaviour if it receives an integer which is outside
the range of int.

One way is to write a routine that excepts an arbitrary large
input line by dynamically allocating space for it (samples have
been posted to clc on numerous occasions), and then parse that
input using strtol (making use of the 'end' pointer).

If you're willing to flag multiple leading zeros as an error, then
you can fix your buffer to a compile time fixed limit.

.... snip ...

Try these, after suitable #includes. No buffers needed. Build int
input routines around them. The only nuisance for that is a
guaranteed method of negating values without creating an integer
overflow.

/* --------------------------------------------------------------
* Skip to non-blank on f, and return that char. or EOF. The next
* char that getc(f) will return is unknown. Local use only,
* because it violates the principle of leaving the terminating
* char in the input stream.
*/
static int ignoreblks(FILE *f)
{
int ch;

do {
ch = getc(f);
} while ((' ' == ch) || ('\t' == ch));
/* while (isblank(ch)); */ /* for C99 */
return ch;
} /* ignoreblks */

/*--------------------------------------------------------------
* Read an unsigned value. Signal error for overflow or no
* valid number found. Returns 1 for error, 0 for noerror, EOF
* for EOF encountered before parsing a value.
*
* Skip all leading blanks on f. At completion getc(f) will
* return the character terminating the number, which may be \n
* or EOF among others. Barring EOF it will NOT be a digit. The
* combination of error, 0 result, and the next getc returning
* \n indicates that no numerical value was found on the line.
*
* If the user wants to skip all leading white space including
* \n, \f, \v, \r, he should first call "skipwhite(f);"
*
* Peculiarity: This specifically forbids a leading '+' or '-'.
*/
int readxwd(unsigned int *wd, FILE *f)
{
unsigned int value, digit;
int status;
int ch;

#define UWARNLVL (UINT_MAX / 10U)
#define UWARNDIG (UINT_MAX - UWARNLVL * 10U)

value = 0; /* default */
status = 1; /* default error */

ch = ignoreblks(f);

if (EOF == ch) status = EOF;
else if (isdigit(ch)) status = 0; /* digit, no error */

while (isdigit(ch)) {
digit = ch - '0';
if ((value > UWARNLVL) ||
((UWARNLVL == value) && (digit > UWARNDIG))) {
status = 1; /* overflow */
value -= UWARNLVL;
}
value = 10 * value + digit;
ch = getc(f);
} /* while (ch is a digit) */

*wd = value;
ungetc(ch, f);
return status;
} /* readxwd */

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Jan 31 '06 #7
On Tue, 31 Jan 2006 14:31:31 +0100, serrand <xa************@free.fr>
wrote:
Peter Nilsson wrote:

#define BIG_ENOUGH_FOR_INT \
( (int) (sizeof(int) * CHAR_BIT + 11) / 3) )

( (int) (sizeof(int) * CHAR_BIT + 5) / 3) )
is enough for signed, isn't it?
I wonder why you are using two more places...

That's enough for _unsigned_. Signed requires one more.

But he has two more. In some situations that might allow for a decimal
point (redundant for integer) or a currency symbol, but for just a
number it isn't needed.

- David.Thompson1 at worldnet.att.net
Feb 13 '06 #8

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

Similar topics

7
by: JR | last post by:
Hey all, I have read part seven of the FAQ and searched for an answer but can not seem to find one. I am trying to do the all too common verify the data type with CIN. The code from the FAQ...
10
by: Doug O'Leary | last post by:
Hey, all. I have a perl script which generates the html listed below. I cleaned it up a bit since the perl CGI module creates some really ugly html code. I've looked at this thing 8 ways to...
5
by: William Payne | last post by:
Hello, I am in the process of converting a C++ program to a C program. The user of the program is supposed to supply an integer on the command line and in the C++ version of the program I was using...
7
by: William L. Bahn | last post by:
I recently challenged one of my students to figure out a way to determine if fgets() actually received the entire contents of the input string. When he was having trouble figuring it out even after...
99
by: Mikhail Teterin | last post by:
Hello! Consider the following simple accessor function: typedef struct { int i; char name; } MY_TYPE; const char *
16
by: lawrence k | last post by:
I've made it habit to check all returns in my code, and usually, on most projects, I'll have an error function that reports error messages to some central location. I recently worked on a project...
1
by: halcyon943 | last post by:
have 4 folders that I watch and need to move files from to another location. Three constraints: -Finish time. Make sure the program stops transferring files at a specific time -Number of...
2
by: jou00jou | last post by:
Hi, I have trouble using sscanf and fgets to check for overflow. I will post the assignment specification so I could help whoever would kindly like to offer his/her help. ...
27
by: Aaron Hsu | last post by:
Hey all, After seeing the Secure version I/O functions thread, it occured to me that maybe not everyone agrees with the almost universal adage that I have heard. I have Always been told that...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
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...
0
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...

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.