473,624 Members | 2,264 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 2629
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 000000000000000 000000000000000 00000000012,
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 000000000000000 000000000000000 00000000012,
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 000000000000000 000000000000000 00000000012,
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(unsigne d 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.ne t
Feb 13 '06 #8

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

Similar topics

7
7281
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 looks like this: #include <iostream>
10
2832
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 Sunday, but I can't see anything wrong. When I hit the "Add" button, it immediately executes the action of the form skipping the validate_form function completely. I've tried the script section towards the top of the html as well as just before...
5
11045
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 something called stringstreams to do the conversion. Here's my C version, can I leave it as it is or does it need to be robustified or changed in any manner, regarding error checking? char* endptr; errno = 0;
7
1765
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 I recommended he look carefully at the difference between the two cases when the input was short enough and when the input was too long, I suggested he look at the FAQ for this newsgroup. He came back and said he couldn't find anything, so I went...
99
5125
by: Mikhail Teterin | last post by:
Hello! Consider the following simple accessor function: typedef struct { int i; char name; } MY_TYPE; const char *
16
2611
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 where someone suggested to me I was spending too much time writing error messages, and that I was therefore missing the benefit of using a scripting language. The idea, apparently, is that the PHP interpreter writes all the error messages that are...
1
1905
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 files transferred. Can only move a certain amount of files per time period. -Folders have a priority. The files have to be moved based on the folder priority.
2
3082
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. ____________________________________________________________________________________ 1) The program should expect 2 decimal integers per line. Let's call these n1 and n2. 2) For each such input line it should output the value of n1 + 2 * n2 (followed by a newline...
27
2278
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 using things like strlcpy and other explicitly bounded functions were better than using the non-bounded versions like strcpy. Is this a matter of good programming style, or is this just needless overhead?
0
8170
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
8675
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...
0
8474
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...
1
6108
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
4078
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4173
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2604
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1784
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1482
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.