473,396 Members | 1,655 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,396 software developers and data experts.

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

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;
}
Nov 14 '05 #1
6 2792

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();
}


Nov 14 '05 #2
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" <my*****@gmail.com> wrote in message
news:11*********************@f14g2000cwb.googlegro 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();
}

Nov 14 '05 #3
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
Nov 14 '05 #4
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
Nov 14 '05 #5
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 <cb********@yahoo.com> wrote in message news:<42***************@yahoo.com>...
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.

Nov 14 '05 #6
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

Nov 14 '05 #7

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

Similar topics

8
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...
7
by: jmac | last post by:
Greetings fellow programmers, I have created a C program that has a few bugs and would like to get some help with working them out. Here is a list of the problems that I am experiencing: -...
6
by: hpy_awad | last post by:
I am writing stings ((*cust).name),((*cust).address)to a file using fgets but rabish is being wrote to that file ? Look to my source please and help me finding the reason why this rabish is being...
7
by: happy | last post by:
I will reissue my question . How to form and write string field to a disk file in one statement usinf fprintf? my struct as below : struct record { char customer_name; int customer_no;...
3
by: happy | last post by:
How will I read a string using scanf in that function : to the write what scanedf will be written using fprintf customer_input(cust) /*---------------------*/ struct customer_record *cust; {...
25
by: sravishnu | last post by:
Hello, I have written a program to concatanae two strings, and should be returned to the main program. Iam enclosing the code, please give me ur critics. Thanks, main() { char s1,s2;...
0
by: georges the man | last post by:
The purpose: • Sorting and Searching • Numerical Analysis Design Specification You are to write a program called “StockAnalyser”. Your program will read a text file that contains historical...
1
by: Smita Prathyusha | last post by:
I am facing a problem in writing to COM1. I am using a Win 32 Console mode Program in VC++ the following is the code: If anyone can help me out it will be of great help : // SC_Using_Classes.cpp...
5
by: zehra.mb | last post by:
Hi, I had written application for storing employee data in binary file and reading those data from binary file and display it in C language. But I face some issue with writing data to binary file....
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
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...
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
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,...

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.