this is a menu driven program having two functions. everything works fine if i enter numbers but when i enter character it runs infinite times sometimes :(
like when i enter integers it works fine and if i enter char it shows some junk value and then try again option is showed and i again enter char it runs infinite times
#include<stdio.h>
#include<conio.h>
#include<math.h>
void cal()
{
int x,y,z;
printf("enter two numbers\n");
scanf("%d%d",&x,&y);
z=x+y;
printf("%d\n",z);
}
void mul()
{
int x,y,z;
printf("enter two numbers\n");
scanf("%d%d",&x,&y);
z=x*y;
printf("%d\n",z);
}
void main()
{
int x,c;
clrscr();
menu :
printf("1.sum\n");
printf("2.mul\n");
printf("enter choice\n");
scanf("%d",&x);
switch(x)
{
case 1:cal();break;
case 2:mul();break;
default :printf("try again\n");
}
printf("press 5 to run another function\n");
scanf("%d",&c);
if(c==5)
{
goto menu;
}
getch();
}
You could try updating your gcc compiler. I ran the code on gcc 4.8 and the code terminated well for characters as well.
Otherwise if you really want to handle characters as well you take an input using a char pointer (string that is ) and then using atoi(str) store it in an int variable and then process it. And you can check : if the user enters characters ( using isalpha() ) then terminate the code.
Sample Code : (ran well enough)
char *s = malloc(64);
scanf("%s",s);
if(isalpha(s[0]))
return ;
else
int x = atoi(s);
int sum = x + 1; //or whatever manipulations you need to do
"when i enter character it runs infinite times sometimes ..."
All the code that tries to read an int uses the following of some sort. When non-numeric data is entered, scanf("%d", ... does not consume that IO (leaving it for the next IO operation), does not set c to any value, and then returns a 0 (which is not tested). At that point c has whatever value it had before the scanf() call. Since c was not initialized, its value could be anything - hence undefined behavior as suggested by #BLUEPIXY
int c;
...
scanf("%d",&c);
Since the non-numic data is left for the next IO and the next IO could be another scanf("%d", code is stuck in a rut - infinite loop.
To best fix, initialize variables, get the user input via fgets() and detemrine the value via sscanf() or strtol().
int c = 0;
char buf[80];
if (fget(buf, sizeof buf, stdin) == NULL) Handle_EOForIOerror();
if (sscanf(buf, "%d",&c) != 1) Handle_NonNumericInpupt();
Related
I'm extremely new to C coding and i'm wondering why this is crashing like this? After I input a value and press enter, my program instantly crashes. I remember learning there are times when you use a & with an array in the scanf line and sometimes you don't. So when I remove the & it crashes instantly. I'm not sure how to troubleshoot this problem and would appreciate help.
What i'm trying to accomplish:
"Write a program that asks the user to enter a sequence of integers terminated by 0 ( the last number is 0) and prints all the numbers entered on one line."
The program crashes before I can enter the other variables. I was not done coding but since it keeps crashing instantly I can't go further.
int main () {
int ru[1000];
int read;
int nums;
int counts;
printf("Enter integers, press 0 to end user input \n");
while (nums>0) {
scanf("%d",&ru[nums]);
if (nums==0)
printf("%d ", ru[nums]);
}
system("pause>nul");
return 0;
}
As noted by several people already, you don't ever assign a value to nums at any point in your code, but make use of it in several places.
You should populate nums and whilst it's more than zero (this should probably be not equal to zero if you want to also include negative integers), store it's value into your array. You can track where you are in the array using another variable (I've picked the read one that you'd already declared), making sure that it is first initialised to 0.
Once the while loop is terminated, either by nums being zero or you filling up the array, you can then print out the numbers you've collected.
int main (void) {
int ru[1000];
int read=0;
int nums;
int counts;
printf("Enter integers, press 0 to end user input \n");
scanf("%d",&nums);
while ((nums>0)&&(read<1000)) {
ru[read++]=nums;
scanf("%d",&nums);
}
for(counts=0;counts<read;counts++) {
printf("%d ",ru[counts]);
}
printf("\n");
system("pause>nul");
return 0;
}
The scanf() you are using as the following prototype:
int scanf(const char *format, ...);
you should give the de pointer to the buffer variable as a parameter but your are giving a pointer to an array (pointer to a pointer).:
scanf("%d",&ru[nums]);
A solution to your problem might be:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int ru[1000];
int i = 0;
printf("Enter integers, press 0 to end user input \n");
do
{
scanf("%d",&ru[i]);
}while (ru[i]!= 0 && i++ < 1000);
for(i = 0; ru[i] != 0 ; i++)
printf("%d ", ru[i]);
return EXIT_SUCCESS;
}
When I compile my code it says that everything checks out but when I run it nothing happens. The program just runs until I kill the terminal.
#include<stdio.h>
int main()
{
float work;
work=0;
char ans[]="No";
while(ans[0]=='N');
{
printf("Hours worked today ");
scanf("%f", &work);
printf("Is that all? ");
scanf("%s", ans);
}
return 0;
}
You have put a ; after the while condition. Therefore your while loop is empty and will run forever.
The more readable equivalent of your program is this:
int main()
{
float work;
work=0;
char ans[]="No";
while(ans[0]=='N')
{
// empty loop thAT will run forever
}
// we never get here
printf("Hours worked today ");
scanf("%f", &work);
printf("Is that all? ");
scanf("%s", ans);
return 0;
}
In your program juste change
while(ans[0]=='N');
to
while(ans[0]=='N')
and it will work.
char ans[]="No";
...
scanf("%s", ans);
ans can hold only a string of length 2. You should make ans larger, to be able to hold any reasonable input, e.g.:
char ans[200] = "No";
Another problem is the ; after the while:
while(ans[0]=='N');
^
Remove it. It makes an empty instruction the only thing the while repeats.
Another thing: when dealing with user input, be it stdin or file input, you should check if the read was done successfully, in you case you should check the return value of scanf
Simply change
while(ans[0]=='N');
to
while(ans[0]=='N')
, because the former is identical to
while(ans[0]=='N')
{
;
}
,which will never end.
So I'm working on basic C skills, and I want to design a code which enters as many numbers as the user wants. Then, it should display the count of positive,negative & zero integers entered.
I've searched Google & StackOverflow. The code seems fine according to those programs.
It compiles & runs. But whenever I input anything after the prompt "enter more? y/n", it returns to the code..
Please have a look at the code below:
#include<stdio.h>
int main()
{
int no,count_neg=0,count_pos=0,count_zero=0;
char ch='y';
clrscr();
do
{
puts("Enter number");
scanf("%d",&no);
if (no>0)
count_pos++;
else if (no<0)
count_neg++;
else
count_zero++;
puts("want more? - y/n ");
scanf("%c",&ch);
}
while (ch=='y');
if (ch=='n')
{
printf("No of positives = %d",count_pos);
printf("No of negatives = %d",count_neg);
printf("No of zeros = %d",count_zero);
}
getch();
return 0;
}
The problem is with "scanf("%c", &ch);"
What happens actually is :
Suppose you enter 'y' as a choice and hit 'enter'(return), the return is a character and
its character value is 10(since its a new line character), thus the scanf takes the 'return'
as its input and continues.
Solution :
1. use getchar() before scanf()
// your code
getchar();
scanf();
//your code
getchar() takes the return value as its input, thus you are left with your actual value.
add '\n' to scnaf()
// code
scanf("\n%c", &ch);
//code
when scanf() encounters the '\n' character it skips it (google about scanf, to know how
and why ), thus stores the intended value inside 'ch'.
A "better" form for:
int main()
is:
int main(void)
clrscr is not standard C.
You ought to check the return-value of any function which might indicate "interesting status," such as a failure condition, and from which you can gracefully deal with the situation. In this case, scanf is such a function.
I believe that your first do ... while condition will become false because it will pick up the newline character following your first scanf call. You might want to read about getchar or getc, instead of using scanf for the task of checking whether or not to run the loop again. You can "eat" unwanted characters, including a newline.
Here, I have corrected the problem. The problem was this that the "enter" you press after each number is a character and is takenup by the scanf() as it is there to scan some characters. So I have added a getchar(); before the scanf();so the "enter" is taken up by getchar(); and scanf() is now free to take your input.
#include<stdio.h>
int main()
{
int no,count_neg=0,count_pos=0,count_zero=0;
char ch='y';
clrscr();
do
{
puts("Enter number");
scanf("%d",&no);
if(no>0)
count_pos++;
else if(no<0)
count_neg++;
else
count_zero++;
puts("want more? - y/n ");
getchar();//<---- add this here
scanf("%c",&ch);
}
while(ch=='y');
if(ch=='n')
{
printf("No of positives = %d",count_pos);
printf("No of negatives = %d",count_neg);
printf("No of zeros = %d",count_zero);
}
getch();
return 0;
}
To fix the input is to use a C String like this scanf("%s",...);
This might break if you input more than one character because scanf will keep reading until the user hits enter, and your ch variable is only enough space for one character.
I run your code in Online compiler. I am not sure about other compiler.
I slightly changed your code. i.e., first i read char then int. If i do not change the order, char variable holds int variable value. This is the reason ( ch variable holds values of no variable).
#include<stdio.h>
int main()
{
int no,count_neg=0,count_pos=0,count_zero=0;
char ch='y';
do
{
puts("Enter number");
scanf("%c",&ch);
scanf("%d",&no);
if(no>0)
count_pos++;
else if(no<0)
count_neg++;
else
count_zero++;
puts("want more? - y/n ");
}
while(ch=='y');
if(ch=='n')
{
printf("No of positives = %d",count_pos);
printf("No of negatives = %d",count_neg);
printf("No of zeros = %d",count_zero);
}
return 0;
}
EDIT:
whenever integer and char are read through keyboard. it stores int value and enter key value. so this is the reason.
You have to add
scanf("%d",&no);
you code
......
.....
fflush(stdin);
scanf("%c",&ch);
use:
ch = getche();
instead of:
scanf("%c", &ch);
I have a some code, and the function I am having trouble with is this:
unsigned int getInputData() {
printf("Please input a positive integer number terminated with a carriage return.\n");
do{
scanf("%c", &input);
if(isdigit(input)) {
temp = charToInt(input);
rValue = mergeInt(rValue, temp);
}
if(rValue >= imax) {
rValue = 0;
printf("ERROR: That is too large of an integer. Please try again. \n");
}
else if(isalpha(input)){
rValue = 0;
printf("This is not a integer. Please try again. \n");
}
else{
printf("OK. This is a good number. \n");
}
} while(1);
}
I'm scanning in each char individually, merging it into an int. Which is exactly what I want to do BUT I only want it to print "OK. This is a good number." once when the user types it in. Example: If someone was to type in: 12345 I want it to return: "OK. This is a good number." once for those 5 char rather than once each. Hoping this makes sense, been at it for awhile so anything will help.
There's huge logic problems behind your code:
You loop infinitely without checking for end of input:
You say you want to tell whether this is a good number when the user inputs several digits, but you do only read one character at a time, and you do not define how a number ends.
Though you do specify to end with a carriage return, you did not design your algorithm that way, you never check for the \n character.
You define a return value for the getInputData() function but you do never return from that function.
You test whether input is a digit to update the value, but for errors you do show an error only if it's an alphabetic character.
Basically, to keep with the way you wrote your algorithm, here's another take:
unsigned int getInputData() {
char input;
long value=0;
do {
scanf("%c", &input);
if (isdigit(input))
value = value*10+input+'0';
else if (input == '\n')
return 1;
else
return 0;
} while(1);
}
int main() {
printf("Please input a positive integer number terminated with a carriage return.\n");
if (getInputData() == 1)
printf("OK. This is a good number.\n");
else
printf("This is not a integer. Please try again. \n");
return 0;
}
but I do exit from the infinite loop to be able to check the result.
N.B.: for the purpose of the example, I did not check for overflows.
N.B.1: I kept using scanf() to stay close to your code, but if you only want to read one character at a time, it is better to use getchar() which is way simpler and faster.
N.B.2: you can also simplify your code by using more features of scanf():
unsigned int getInputData() {
unsigned input;
long value=0;
int n;
do {
n = scanf("%u", &input);
if (n == 0)
return 0;
else
return 1;
} while(1);
}
You may even try to use scanf("%a[0-9]") which is a GNU extension. See man scanf for more details.
In the below program I try to input a number between 1 to 100 but if I enter a 'character' or "string" ( like s or sova ) during the execution time of scanf() statement it creates a infinite loop. so I try to do .... when I input a string or a character it shown me a message like "wrong value entered. enter again" and it will enter again...
Thanx;
#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
while(!(a>=1&&a<=100))
{
printf("wrong value entered. enter again\n");
scanf("%d",&a);
}
printf("you enter %d. Thanxz",a);
return 0;
}
You need to check the return value of scanf
If the user has not entered a integer, you need to eat the input. The scanf function will continually say not a integer, try again. So if scanf returns 0 you need to deal with it
When you use scanf you are working with buffered input, this means that when you enter a value say "123" and press ENTER then "123" plus the ending character (ENTER) will all be added to the buffer. scanf then removes 123 since %d specifies that an integer should be read but if a user enters something invalid like a string instead then the buffer will not be emptied.
A better way to read input from the keyboard is to use fgets() where you specify a max length to read. Once you have the input you can use sscanf() to retrieve the numeric value from it. The ENTER till then not irritate your input.
char buffer[128];
fgets( buffer, 128, stdin );
sscanf( buffer, "%d", &a );
Also always check return values from functions as a rule of thumb so that you can do appropriate action if the function fails.
If the return value from scanf is not equal to the number of item you like the user to input, read all characters of the input buffer until there is a '\n'. But instead of copying a whole loop over and over again to the places in your code where the user should input something, you could wrap the loop in a function like this:
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void input(const char *format,...)
{
va_list ap;
int r;
/* number of items [to read] */
int noi=0;
for(r=0;r<strlen(format)-1;r++)
{
if(format[r]=='%')
{
if(format[r+1]!='%')
noi++;
else
r++;
}
}
do
{
va_start(ap,format);
r=vscanf(format,ap);
va_end(ap);
if(r!=noi)
{
switch(r)
{
case EOF:
case 0:
printf("All wrong, try again!\n");
break;
default:
printf("Unexpected value after item no %d!\n",r);
}
while(getc(stdin)!='\n');
}
else
break;
} while(1);
}
Hope that helps,
Jan
Try this.
#include <stdio.h>
#define FLUSH while (getchar() != '\n') // macro to eat invalid input
int main (void) {
int a = 0;
printf ("Enter an integer: ");
scanf("%d", &a);
while (a < 1 || a > 100) {
FLUSH;
printf("Invalid input. Please try again: ");
scanf("%d",&a);
}
printf("You entered %d.\nThanks!\n", a);
return 0;
}
Your code shows several coding habits that need to be changed:
Include (void) in the parameter list of main().
Leave spaces on either side of binary operators: while(!(a>=1&&a<=100)) is needlessly ugly and hard to read.
Simplify your logical expressions. Why use (! (a>=1 && a<=100)) when it means the same thing as (a < 1 || a > 100), and the latter is so much easier to read?
Prompt for user input when needed. Don't have the cursor just sit at a blank line with no indication to the user about what to do.
Use proper grammar and capitalization in your prompts. There's no reason to be lazy in your programming.