473,581 Members | 2,783 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Input Verification

Hello all,

As stated in another message, it's been a long time since I've done any
C coding and I'm not feeling comfortable that I'm doing this correctly.
Basically, I'd like to verify that my supplied input is alphanumeric.
White space and opening/closing parenthesis are also permitted.
Nothing more, nothing less.

Additionally, despite having read my documentation for scanf(), I'm
uncertain how --if it's even possible-- to have a variable input width.
This isn't so much a big deal; but, it would be nice to only have to
modify my symbolic constant rather than keeping track of two maximum
buffer lengths.

Lastly, the code needs to be portable. I understand that there are
probably better platform-specific methods for flushing the input buffer;
however, I'll have to implement these on an individual basis. Assuming
I have no disguised bugs in the FLUSH_IN() macro that you believe I'm
missing, I'm perfectly content with its current implementation.

On a side note, the input will rarely, if ever, actually be supplied by
a user as this is actually planned to be part of an embedded system
project (robot) I'm building in my free time. Ideally, I'll have some
form of GUI or whatever that automatically sends the proper commands
through the serial port. But this is still a good test to get myself
back in the swing of things.

--- Start Code ---
#include <stdio.h>

#define LINE_LIMIT 80
#define MAX_INPUT_SIZE 60
#define PROMPT "%> "

#define FLUSH_IN(fp) do { \
int ch; \
while((ch = fgetc(fp)) != EOF && ch != '\n'); \
} while(0)

void get_command(voi d);

int main(void)
{
get_command();
return 0;
}

void get_command(voi d)
{
int ret;
char input[MAX_INPUT_SIZE];

printf("%s", PROMPT);
while ((ret = scanf("%60[a-z[A-Z[0-9[()[ ]", input)) == EOF || ret == 0)
{
printf("Invalid input...\n");
FLUSH_IN(stdin) ;
}

printf("%s\n", input);
}

--- End Code ---

Any comments are welcome.

Thank you in advance,

--
Sean
Nov 15 '05 #1
3 2836
>As stated in another message, it's been a long time since I've done any
C coding and I'm not feeling comfortable that I'm doing this correctly.
Basically, I'd like to verify that my supplied input is alphanumeric.
White space and opening/closing parenthesis are also permitted.
Nothing more, nothing less.

Additionally , despite having read my documentation for scanf(), I'm
uncertain how --if it's even possible-- to have a variable input width.
Use fgets(). Then you can use a function like the one below to
check the input:

#include <ctype.h>
int verify_input(ch ar *s)
{
/* returns 1 on valid input, 0 on invalid input */
char *p;

for (p = s; *s; s++) {
if(isalnum((uns igned char)*s) ||
isblank((unsign ed char) *s) || *s == '('
|| *s == ')' || *s == '\n') {
/* ok */
} else {
return 0; /* invalid input */
}
}
return 1; /* all input was valid */
}

If you read ALL the input from one line, then check it, you don't
have to worry about flushing. You need to allow a newline (or lop
it off beforehand) if you're getting input from fgets(). If you really
need scanf() parsing, use sscanf() on the line you got from fgets().
This isn't so much a big deal; but, it would be nice to only have to
modify my symbolic constant rather than keeping track of two maximum
buffer lengths.

Lastly, the code needs to be portable. I understand that there are
probably better platform-specific methods for flushing the input buffer;
however, I'll have to implement these on an individual basis. Assuming
I have no disguised bugs in the FLUSH_IN() macro that you believe I'm
missing, I'm perfectly content with its current implementation.
If a user typed it, the program should pay attention to it, if only
to parse over it.
On a side note, the input will rarely, if ever, actually be supplied by
a user as this is actually planned to be part of an embedded system
project (robot) I'm building in my free time. Ideally, I'll have some
form of GUI or whatever that automatically sends the proper commands
through the serial port. But this is still a good test to get myself
back in the swing of things.

--- Start Code ---
#include <stdio.h>

#define LINE_LIMIT 80
#define MAX_INPUT_SIZE 60
#define PROMPT "%> "

#define FLUSH_IN(fp) do { \
int ch; \
while((ch = fgetc(fp)) != EOF && ch != '\n'); \
} while(0)
You don't need FLUSH_IN() if you use fgets() for input consistently.

void get_command(voi d);

int main(void)
{
get_command();
return 0;
}

void get_command(voi d)
{
int ret;
char input[MAX_INPUT_SIZE];

printf("%s", PROMPT);
while ((ret = scanf("%60[a-z[A-Z[0-9[()[ ]", input)) == EOF || ret == 0)
A significant problem with scanf() for this kind of use is that if
the user types an illegal character after some valid input, it
terminates the valid input immediately. For those familiar with
SQL, this can be a disaster: consider "delete from table where
account = 9749879191873" when you accidentally send the command
right after the 'table' part. Bye, bye data.

I recommend reading all the data, THEN checking it. Especially if
the input can be simply described as "a line of input", with other
constraints to be checked later.
{
printf("Invalid input...\n");
FLUSH_IN(stdin) ;
}

printf("%s\n", input);
}

--- End Code ---

Any comments are welcome.


Gordon L. Burditt
Nov 15 '05 #2
Gordon Burditt wrote:
As stated in another message, it's been a long time since I've done any
C coding and I'm not feeling comfortable that I'm doing this correctly.
Basically, I'd like to verify that my supplied input is alphanumeric.
White space and opening/closing parenthesis are also permitted.
Nothing more, nothing less.

Additionall y, despite having read my documentation for scanf(), I'm
uncertain how --if it's even possible-- to have a variable input width.

Use fgets(). Then you can use a function like the one below to
check the input:


Funny thing is that I actually started out with fgets and opted to go
against it because (for whatever reason) I thought it would be easier
using scanf() since I wouldn't have to remove the trailing '\n'. Little
was I aware that what little I saved by not having to remove one extra
character, lead to an excessive amount of code to verify valid input.
By taking your advise and using fgets(), I don't think it took me more
than 10 - 15 minutes to code all of the necessary parsing code, which,
in the end, worked better than my original scanf() code that took me
about an hour to work on (granted I did have to read the documentation
for scanf() again).

[...]
If you read ALL the input from one line, then check it, you don't
have to worry about flushing. You need to allow a newline (or lop
it off beforehand) if you're getting input from fgets(). If you really
need scanf() parsing, use sscanf() on the line you got from fgets().


Another nice thing about scanf() was the ability to check for valid
input using regular expressions. But, in the end, I determined that I
was doing so much parsing, anyhow, that the benefits of using regular
expressions were almost non-existent.
This isn't so much a big deal; but, it would be nice to only have to
modify my symbolic constant rather than keeping track of two maximum
buffer lengths.

Lastly, the code needs to be portable. I understand that there are
probably better platform-specific methods for flushing the input buffer;
however, I'll have to implement these on an individual basis. Assuming
I have no disguised bugs in the FLUSH_IN() macro that you believe I'm
missing, I'm perfectly content with its current implementation.

If a user typed it, the program should pay attention to it, if only
to parse over it.


Again, I like your advise. Although it's doubtful that anybody other
than I will ever do anything with this robot, it's still good practice.
If this were a product I bought off the shelf, I would certainly hope
that the programmers built some form of validation code.

[...]

Thank you much for your input. I like the new design a lot more than I
did my original.

--
Sean
Nov 15 '05 #3
A few nits in addition to the other (good) answers:

On Wed, 03 Aug 2005 13:44:23 -0400, "Fao, Sean"
<en**********@y ahoo.comI-WANT-NO-SPAM> wrote:
#define LINE_LIMIT 80
#define MAX_INPUT_SIZE 60
#define PROMPT "%> " int ret;
char input[MAX_INPUT_SIZE];

printf("%s", PROMPT);
while ((ret = scanf("%60[a-z[A-Z[0-9[()[ ]", input)) == EOF || ret == 0)


To use *scanf %[ or %s or %Nc safely you need a count _one less_ than
the array size: %59[etc] for char input[60]. It's somewhat fragile to
do this with a #define for one (perhaps off in a header file) and the
other written inline; one mildly ugly fix(?) is:

#define MAXIN 60 /* must be a single integer, NOT an expression */

char buff [MAXIN + 1];
#define XSTR(x) #x
#define XSTR2(x) XSTR(x)
.... scanf ("%" XSTR(MAXIN) "[etc]", etc) ...

Note that fgets(), which you report you have already switched to, does
not have this problem: char buf[N] and fgets (buf, N, fd) is correct.

Also, the range notation a-z is NOT standard C although it is a common
extension, and you do NOT use more left-brackets [ to "continue" the
charclass: what you wrote allows (on most implementations ) a-z A-Z 0-9
parens space AND left-bracket (redundantly), which is not what you
asked for; to get that you would use %60[a-zA-Z90-9() ] or in standard
%60[abc<etc. to>XYZ012345678 9() ]

Also note that "whitespace " in computer terminology, especially
Internet, doesn't mean only the space character, it also includes tab,
carriage-return and linefeed or newline (latter especially in C), and
form-feed and vertical-tab where those exist. If you really meant
"whitespace " add those to your charclass or similar logic; if you've
changed to parsing the fgets'ed line explicitly and use isspace() from
<ctype.h> it already handles all these. If you really meant only
"space" say exactly that for clarity.

- David.Thompson1 at worldnet.att.ne t
Nov 15 '05 #4

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

Similar topics

6
2459
by: Boyd Reilly | last post by:
I have a form that has the user pick the type of question he will answer. The input field will be a text, numeric or date type. So, after the question is answered, I need to change the input statement. This resembles what I am doing: <form name="frm1"> Step 1 - Choose a File: <select name="selA" OnChange="makeinputbox;" width="200"...
13
9602
by: Stumped and Confused | last post by:
Hello, I really, really, need some help here - I've spent hours trying to find a solution. In a nutshell, I'm trying to have a user input a value in form's textfield. The value should then be assigned to a variable and output using document.write. (Note, there is no submit button or other form elements. Basically
7
2874
by: SOR | last post by:
Although this currently defeats the spam bots in some respects - isnt it just a mater of time before the spammers figure out a way to verify a signup via email using rotating disposable email addresses or whatever . And if so , Would it not be a good idea to separate the url and signup verification code in the welcome email *now* rather than...
5
2215
by: google | last post by:
first, a little background... i have a C program which preprocesses some data, and then outputs the results into a text file. that text file, in turn, is used as input to a FORTRAN computational fluid dynamics (CFD) program. the FORTRAN program goes to work on the provided data, and outputs a text file which i read back in with another C...
7
2627
by: Hulo | last post by:
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...
2
6928
by: jackson2005 | last post by:
OK, I need to do three different things. On the ONLOAD event I would like a popup box to open. In this popup box I need two text boxes. One for the UserName and one for the BillingTo name. After entering these two items the user can either hit the enter key or press the submit button. The popup window will close and then those two text...
0
2179
by: pwilliams | last post by:
NCOALink Change of Address Verification Each year over 40 million Americans change their mailing addresses. This change is equivalent to every person in California deciding to change addresses and not tell you that they have moved. This uncertainty results in wasted spending on undeliverable address mail, returned mail and processing fees...
13
5479
by: Kal | last post by:
I have a small console app that started out in dotnet 1.1 in VS 2003. That version can be copied to a W2K3 server where it runs fine. I set up a new project in VS 2005 and copied the code files from 2003 to 2005 where they compile and run, no problem. When I copy the two files (exe & dll) to the same W2K3 server they fail with the Strong...
5
1578
by: Mike P | last post by:
Does anybody know how to/have an example of using image verification of user input (i.e. the user has to enter the digits in an image as well as the normal input)? *** Sent via Developersdex http://www.developersdex.com ***
0
7876
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...
0
8156
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. ...
0
8180
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...
0
6563
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...
1
5681
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...
0
5366
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...
0
3832
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1409
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1144
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...

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.