Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > problems writing a printf/scanf function that handles both int and char input from the console

Reply
Thread Tools

problems writing a printf/scanf function that handles both int and char input from the console

 
 
Dawn Minnis
Guest
Posts: n/a
 
      02-06-2005
Hi (running Win xp and developing using Miracle C. Running applications in
windows command prompt)

I'm new to the group so be gentle with me. I am currently writing a C
program to perform matrix by matrix (mxm) and matrix by vector (mxv)
multiplication, so obviously one of my first considerations is to ask the
user if they want an mxm or mxv multiplication performed. I have written the
code below (this is a working snippet of the current, substantially larger
program I am working on. My problem at the moment, is that when I run this
code and enter any integer from 0-9 it handles the error accordingly and
iterates around the loop until the values 1 or 2 are entered. Upon which it
prints "successful response" and finishes (again cut down and missing all
the other queries and algorithms).

Now, here comes the problem. When I enter in characters or symbols OTHER
than integers it spirals into a never ending loop, that I can only exit by
closing the command prompt window.

So, can anyone take a quick look at this program and spot for me what I
assume would be a glaringly obvious reason for this to happen? Such as the
use of int for the function declaration, or %d when reading in the value.
But I don't know how to correct the program so that it "accepts" all
possibilities and then handles them.

Thanks, kind regards
Dawn
-*-*-*-program
below-*-*-*-
-----------------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>

int main()
{
int doMMorMV;
printf("Do you wish to perform MxM or MxV? \nPlease enter 1 for MxM or 2 for
MxV: ");
scanf("%d", &doMMorMV);

while(doMMorMV != 1 && doMMorMV != 2)
{
//call reiterative error message 1
doMMorMV = error1();
}

printf("successful response");

return 0;
}

//reiterative error message 1
int error1()
{
int doMMorMV;
printf("\n Error, not a valid response, \n\t please enter 1 for MxM or 2 for
MxV: \n");
scanf("%d", &doMMorMV);
return doMMorMV;
}


 
Reply With Quote
 
 
 
 
Mysidia
Guest
Posts: n/a
 
      02-06-2005

Dawn Minnis wrote:

> int main()
> {
> int doMMorMV;
> printf("Do you wish to perform MxM or MxV? \nPlease enter 1 for MxM

or 2 for
> MxV: ");
> scanf("%d", &doMMorMV);


Suppose the user enters 'blah'

Scanf will fail to read an integer, so it
will return 0, indicating zero items were scanned
successfully.

The value in 'doMMorMV' is not changed, since nothing was
scanned into it, its value is now undefined (could be anything)

'b' will remain at the start of the input, not consumed
by this scanf.

Meaning that the next scanf("%d", &doMMorMV); will also fail,
hence the endless loop.

try

if (scanf("%d", &doMMorMV) < 1) {
/* Error occured.. */

/* Note this does not mean the waiting input item has
been assumed. */
}

> while(doMMorMV != 1 && doMMorMV != 2)
> {
> //call reiterative error message 1
> doMMorMV = error1();
> }


 
Reply With Quote
 
 
 
 
Dawn Minnis
Guest
Posts: n/a
 
      02-07-2005
Thanks for your quick response

I have spent the last while trying different variations using that but it
doesn't seem to like it. I have moved on.

My next challenge is to read in a string and parse it as an integer. I am
attempting to use the atoi() function but it throws back a weird response.
eg if I pass it 234 it read in 2my. Any idea why this is?

also is there a C equivalent to declaring a string?

I only started programming in C about 3-4 weeks so the function calls are
very different. what I want to do is like this:

String userInput;
int intVal;
...
userInput = System.in.readln();
intVal = Integer.parseInt(userInput);
...

But thats java. And I need it in C.

"Mysidia" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
>
> Dawn Minnis wrote:
>
>> int main()
>> {
>> int doMMorMV;
>> printf("Do you wish to perform MxM or MxV? \nPlease enter 1 for MxM

> or 2 for
>> MxV: ");
>> scanf("%d", &doMMorMV);

>
> Suppose the user enters 'blah'
>
> Scanf will fail to read an integer, so it
> will return 0, indicating zero items were scanned
> successfully.
>
> The value in 'doMMorMV' is not changed, since nothing was
> scanned into it, its value is now undefined (could be anything)
>
> 'b' will remain at the start of the input, not consumed
> by this scanf.
>
> Meaning that the next scanf("%d", &doMMorMV); will also fail,
> hence the endless loop.
>
> try
>
> if (scanf("%d", &doMMorMV) < 1) {
> /* Error occured.. */
>
> /* Note this does not mean the waiting input item has
> been assumed. */
> }
>
>> while(doMMorMV != 1 && doMMorMV != 2)
>> {
>> //call reiterative error message 1
>> doMMorMV = error1();
>> }

>



 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      02-07-2005
Dawn Minnis wrote:
>

.... snip ...
>
> Now, here comes the problem. When I enter in characters or symbols
> OTHER than integers it spirals into a never ending loop, that I can
> only exit by closing the command prompt window.
>
> So, can anyone take a quick look at this program and spot for me
> what I assume would be a glaringly obvious reason for this to
> happen? Such as the use of int for the function declaration, or
> %d when reading in the value. But I don't know how to correct the
> program so that it "accepts" all possibilities and then handles
> them.
>

.... snip unindented code with over long lines ...
(because it is too ugly to read)

In general, if you input values with scanf the char that terminates
the input or signals that the input cannot be done at all, remains
in the input stream. You have to get rid of it. Now lets change
your mechanism to something general (untested code, I am just
writing things down on the fly). Lets say you want to get one of
the chars in a specified string and reject everything else.
Meanwhile you want to prompt with something:

/* flush stdin until a '\n' or EOF occurs */
int flushln(void)
{
int ch;

while (('\n' != (ch = getchar())) && (EOF != ch)) continue;
return ch;
} /* flushln */

int getone(const char *prompt, const char* allowed)
{
int entered;

while (1) {
printf("%s", prompt); fflush(stdout);
entered = getchar();
flushln(); /* we only want the first line char */
if (strchr(allowed, entered)) { /* acceptable */
return entered; /* so return it */
}
else {
printf("Invalid entry '%c', retry:\n", entered);
}
}
} /* untested */

Which encapsulates prompting, getting a char, testing validity, and
retrying until the entry is valid. All assuming I have made no
silly goofs above.

So, to get your 1 or 2, you would call:

doMMorMV = getone("Enter 1 or 2 for M or V", "12");

which means you have the friendlier method of:

doMMorMV = getone("Enter M for MM, or V for MV:", "MV");
or
doMMorMV = getone("Enter M for MM, or V for MV:", "MmVv");

with confidence that you are getting something you expect and that
you have gobbled a complete input line. This simplifies life
greatly.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson


 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      02-07-2005
On Mon, 07 Feb 2005 00:00:31 +0000, Dawn Minnis wrote:

> Thanks for your quick response
>
> I have spent the last while trying different variations using that but it
> doesn't seem to like it. I have moved on.
>
> My next challenge is to read in a string and parse it as an integer. I am
> attempting to use the atoi() function but it throws back a weird response.
> eg if I pass it 234 it read in 2my. Any idea why this is?
>
> also is there a C equivalent to declaring a string?
>
> I only started programming in C about 3-4 weeks so the function calls are
> very different. what I want to do is like this:
>
> String userInput;
> int intVal;
> ...
> userInput = System.in.readln();
> intVal = Integer.parseInt(userInput);
> ...
>
> But thats java. And I need it in C.


A good way to read line based input in C is the fgets() function, e.g.

char buffer[100];

if ((fgets(buffer, sizeof buffer, stdin) != NULL) {
int intVal;

if (sscanf(buffer, "%d", &intVal) != 1) {
/* Converison failed */
}
}

You could also use atoi() but that doesn't test for invalid input. A
better function is strtol() which handled bad input including values too
large, but is a bit more complex to use correctly.

Lawrence
 
Reply With Quote
 
kenuplus
Guest
Posts: n/a
 
      02-08-2005
Hi.when getchar works,it firstly look at buffer ,If there is somethink
in buffer
it use what there is .On the contrary,if there is nothing in buffer,it
will wait input from user.After, user enter input and
enter('\n'),getchar only will take input not '\n'.'\n' will stay in
buffer.when again getchar() works,it will take '\n' at buffer,In other
words,getchar() won't wait user's input.so if you cope with your
problem,use flush(stdin) to clear buffer.


CBFalconer <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> Dawn Minnis wrote:
> >

> ... snip ...
> >
> > Now, here comes the problem. When I enter in characters or symbols
> > OTHER than integers it spirals into a never ending loop, that I can
> > only exit by closing the command prompt window.
> >
> > So, can anyone take a quick look at this program and spot for me
> > what I assume would be a glaringly obvious reason for this to
> > happen? Such as the use of int for the function declaration, or
> > %d when reading in the value. But I don't know how to correct the
> > program so that it "accepts" all possibilities and then handles
> > them.
> >

> ... snip unindented code with over long lines ...
> (because it is too ugly to read)
>
> In general, if you input values with scanf the char that terminates
> the input or signals that the input cannot be done at all, remains
> in the input stream. You have to get rid of it. Now lets change
> your mechanism to something general (untested code, I am just
> writing things down on the fly). Lets say you want to get one of
> the chars in a specified string and reject everything else.
> Meanwhile you want to prompt with something:
>
> /* flush stdin until a '\n' or EOF occurs */
> int flushln(void)
> {
> int ch;
>
> while (('\n' != (ch = getchar())) && (EOF != ch)) continue;
> return ch;
> } /* flushln */
>
> int getone(const char *prompt, const char* allowed)
> {
> int entered;
>
> while (1) {
> printf("%s", prompt); fflush(stdout);
> entered = getchar();
> flushln(); /* we only want the first line char */
> if (strchr(allowed, entered)) { /* acceptable */
> return entered; /* so return it */
> }
> else {
> printf("Invalid entry '%c', retry:\n", entered);
> }
> }
> } /* untested */
>
> Which encapsulates prompting, getting a char, testing validity, and
> retrying until the entry is valid. All assuming I have made no
> silly goofs above.
>
> So, to get your 1 or 2, you would call:
>
> doMMorMV = getone("Enter 1 or 2 for M or V", "12");
>
> which means you have the friendlier method of:
>
> doMMorMV = getone("Enter M for MM, or V for MV:", "MV");
> or
> doMMorMV = getone("Enter M for MM, or V for MV:", "MmVv");
>
> with confidence that you are getting something you expect and that
> you have gobbled a complete input line. This simplifies life
> greatly.

 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      02-08-2005
On Tue, 08 Feb 2005 04:15:21 -0800, kenuplus wrote:

> Hi.when getchar works,it firstly look at buffer ,If there is somethink
> in buffer
> it use what there is .On the contrary,if there is nothing in buffer,it
> will wait input from user.After, user enter input and
> enter('\n'),getchar only will take input not '\n'.'\n' will stay in
> buffer.when again getchar() works,it will take '\n' at buffer,In other
> words,getchar() won't wait user's input.so if you cope with your
> problem,use flush(stdin) to clear buffer.


C has no function called flush() and fflush(stdin) is a serious error in
C, invoking fflush() on input streams invokes undefined behaviour. The
implication here is that you want to read input by line. A good way of
doing that is to use fgets() and then parse the input using C's string
handling facilities.

Lawrence

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
Question about file handles and windows handles @ Windows Operating Systems eino Python 1 05-08-2007 09:14 PM
(const char *cp) and (char *p) are consistent type, (const char **cpp) and (char **pp) are not consistent lovecreatesbeauty C Programming 1 05-09-2006 08:01 AM
int main(int argc, char *argv[] ) vs int main(int argc, char **argv ) Hal Styli C Programming 14 01-20-2004 10:00 PM
newbie: char* int and char *int trey C Programming 7 09-10-2003 03:24 AM



Advertisments