I am writing a piece of code to ask for two specific points in the format P0 x y.
If the user types in Q then the program terminates, for some reason I have trouble outputting the user input (P0 x y) into an output. When I try to run the code and type P0 2 3 it says I have chosen points 0 2.00 3.00.
While the desired output is P0 2 3.
#include <stdio.h>
void main() {
float a, b;
char Q, P, input;
printf("");
scanf("%c", &input);
if (input == 'Q') {
printf("quitting program");
return (0);
} else {
scanf("%c" "%f" "%f", &input, &a, &b);
printf("you have chose points: %c %f %f", input, a, b);
}
return (0);
}
Because you use two scanf. First scanf reads P then second scanf read 0 from command line (from stdin). So after second scanf, input = '0'. This is reason why your program prints 0 2.00 3.00
If you want to print out P0 you have to use string, for example the example below:
#include <stdio.h>
int main()
{
float a, b;
char Q, P, input;
char point[3] = {'\0'};
scanf( "%c" , &input);
point[0] = input;
if(input=='Q')
{
printf("quitting program");
return 0;
}
else
{
scanf( "%c" "%f" "%f", &input, &a, &b);
point[1] = input;
printf("you have chose points: %s %f %f",point, a, b);
}
return 0;
}
As the other answer also mentions, when checking for Q in input, the input byte is consumed. The C standard library provides a fix for this specific problem: you can "return" the consumed byte to the input device (keyboard buffer), and later retry reading from input.
The function is ungetc. It requires quite specific syntax (you should "unget" the same value as was just read; also you must use stdin to specify that you are working with keyboard) and only works for one byte, exactly as you need.
Here is your code with my updates and comments.
#include <stdio.h>
int main()
{
float a, b;
char Q; // only used for checking the "quit" condition
char input[10]; // assuming 9 characters + terminating byte is enough
scanf("%c", &Q);
if(Q=='Q')
{
printf("quitting program");
return (0);
}
else
{
ungetc(Q, stdin); // return one byte to the input device
scanf( "%s" "%f" "%f", input, &a, &b); // "%s" read from the input as string now
printf("you have chose points: %s %f %f",input, a, b);
}
return 0;
}
Related
Here if have used two format specifiers in scan function but it only proceeds after taking three numbers though only two numbers are stored.I don't know why is it waiting for the unnecessary 3rd number.
#include <stdio.h>
int main(){
int a ,b ;
printf("Enter values of a and b ");
scanf(" %d %d " , &a ,&b );
printf("a = %d b = %d" ,a ,b);
return 0;
}
why is it waiting for the unnecessary 3rd number.
" %d %d " directs scanf() to wait for some non-white-space after the 2 int to know all trailing white-spaces are consumed.
" %d %d" directs scanf() to return after the 2 int.
The initial space and the second one are actually redundant since %d reads and ignores whitespace before the number, so you can just write:
scanf("%d%d", &a, &b);
but you should also test that scanf() returns 2 indicating 2 successful conversions.
Here is a modified version:
#include <stdio.h>
int main() {
int a, b;
printf("Enter values of a and b: ");
if (scanf("%d%d", &a, &b) == 2) {
printf("a = %d, b = %d\n", a, b);
} else {
printf("invalid input\n");
}
return 0;
}
don't have this issue when I paste the code into this link https://c.runoob.com/compile/11
// program to detect whether only integer has been given or not
int main() {
int a, b, s;
printf("Enter two proper number\n");
BEGIN:
s = scanf("%d %d", &a, &b); //storing the scanf return value in s
if (s != 2) {
printf("enter proper value\n");
goto BEGIN;
}
printf("The values are %d and %d ", a, b);
}
This program to detect whether only integer has been given or not goes into infinite loop when invalid data is entered instead of asking for new values
why doesn't the goto work here?
Note that when scanf gets bad input (for example you enter cat dog) that input remains in the input buffer until you take steps to clear it out. So the loop keeps repeating and rejecting the same input which is still there.
It is simpler to use fgets and sscanf and if the scan fails, you just forget the input string and get another.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a, b;
char str[42];
do {
printf("Enter 2 numeric values\n");
if(fgets(str, sizeof str, stdin) == NULL) {
exit(1);
}
} while(sscanf(str, "%d%d", &a, &b) != 2);
printf("Numbers are %d and %d\n", a, b);
}
Program session:
Enter 2 numeric values
cat dog
Enter 2 numeric values
cat 43
Enter 2 numeric values
42 dog
Enter 2 numeric values
42 43
Numbers are 42 and 43
Note that goto is poor practice in C and should be used only where there is no other way of constructing the code — which there usually is.
There are multiple reasons scanf() can return a value different from 2:
there is pending input that cannot be converted according to the conversion specification. For example if there is an A pending in the input stream, the %d conversion fails and the A stays in the input stream. Your code just keeps trying this conversion and will never stop. You should read and discard the offending input before re-trying.
the input stream has had a read error or hit the end of file. If at least one conversion succeeded, the number of successful conversions is returned, otherwise EOF is returned. If EOF is returned, there is no point trying again since no more input will be available.
Note also that it is considered bad style to use goto for constructions that are better expressed with flow control statements such as while and for.
Here is a corrected version:
#include <stdio.h>
// program to detect whether only integer has been given or not
int main() {
int a, b, s, c;
printf("Enter two proper numbers: ");
for (;;) {
s = scanf("%d%d", &a, &b); //storing the scanf return value in s
if (s == 2) // conversions successful
break;
if (s == EOF) {
printf("unexpected end of file\n");
return 1;
}
/* discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("Invalid input. Try again: ");
}
printf("The values are %d and %d\n", a, b);
return 0;
}
scanf returns the number of characters. As a result, s will be equal to the number of characters you have written is 2, then your loop will stop. The reason this runs infinitely many times is that the number of characters you have entered differed from 2. Print s to see what value it holds and you will get more information.
as expected this prog. should accept a number until it encounters a 4 but it gives some garbage value. why?
int main(void)
{
int a;
printf("Enter a number: ");
scanf("%[^4]d", &a);
printf("You entered: %d\n", a);
return 0;
}
As far as I know scansets are meant to be used with strings (which makes the d not act as an integer placeholder specification). One way to write it is to read the input into a string and then parse it:
int main(void)
{
int a;
char b[255];
printf("Enter a number: ");
scanf("%254[^4]", &b);
a = atoi(b);
printf("You entered: %d\n", a);
return 0;
}
I'm keeping the modified code to a minimum, you'd definitely need some extra checks for input sanity.
To clarify: The 254 prefix limits the amount of data that scanf will capture, so as to not exceed the size of the buffer (strings are terminated with an extra null character, so the read length must be smaller than the actual size)1.
The scanset working with only characters.
Here is my sample code. (but, I don't know what you really want.)
#include <stdio.h>
int main(void) {
char buffer[128];
printf("Enter a number: ");
scanf("%[^4]s", buffer);
printf("You entered: %s\n", buffer);
return 0;
}
The result is,
Enter a number: 12345678
You entered: 123
Additionally, if you want integer value, use atoi().
I have a requirement to get two integers and add and print the added value. I wrote a working program. Another requirement is to check whether the input value is other than integer and if it is other than integer, without closing the program, it should again ask for the inputs.
C Code
#include <stdio.h>
void main()
{
int a,b,c;
printf("This is a Addition program");
printf("\n Enter value of a:");
scanf("%d",&a);
printf("\n Enter value of b:");
scanf("%d",&b);
c=a+b;
printf("\n The added value is %d",c);
}
Here's some code that will completely fulfil your requirement. Yesterday David C Rankin posted an answer to the same basic question in Stack Overflow.
This code is basically what David provided:
#include <stdio.h>
static int getInt(const char *prompt)
{
int value;
char c;
while(printf("%s",prompt) && scanf("%d", &value) !=1)
{
do { c = getchar(); } while ( c != '\n' && c != EOF ); // flush input
printf ("Invalid Entry, Try Again...\n");
}
return value;
}
int sum(int a , int b) { return ( a + b ); }
int main(){
int a , b;
a = getInt("Please enter a number");
b = getInt("Please enter a number");
printf("Sum is :%d" , sum(a,b));
}
The function getInt check the input and yells for the wrong input.
This program will do what you want
#include<stdio.h>
int main() //use int not void
{
int a,b,c;
printf("This is a Addition program");
printf("\n Enter value of a:");
while(scanf("%d",&a)==0)
{
printf("\n Invalid input.Try again:");
getchar(); // clear the previous input
}
printf("\n Enter value of b:");
while(scanf("%d",&b)==0)
{
printf("\n Invalid input.Try again:");
getchar(); // clear the previous input
}
c=a+b;
printf("\n The added value is %d",c);
return 0; // because main returns int
}
scanf returns the number of successfully read items, so it will return 1 in your case if a valid value was entered. If not, an invalid integer value was entered and scanf will return 0.
Use fgets()/sscanf()/strto...() rather than scanf().
scanf() parses and performs input in the same function and does not well handle unexpected input. Use fgets() for user input and then scan/parse.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
int getint(const char *prompt) {
char buf[sizeof(int) * CHAR_BIT];
while (1) {
fputs(prompt, stdout);
fflush(stdout);
if (fgets(buf, sizeof buf, stdin) == NULL) {
// sample handling of unexpected input issue.
// Value to return of EOF or IO error
return INT_MIN;
}
/// strtol() is another option
int i, n;
// " %n" notes offset of non-white-space after the numebr.
if (1 == sscanf(buf, "%d %n", &i, &n) && buf[n] == '\0') {
return i;
}
}
}
int main(void) {
int a, b, c;
printf("This is a Addition program");
a = getint("\n Enter value of a:");
b = getint("\n Enter value of b:");
c = a + b;
printf("\n The added value is %d", c);
return 0;
}
#include <stdio.h>
int main (void)
{
int T, y, z;
scanf ("%i\n", &T);
for (T; T > 0 ; --T)
{
scanf ("%i\n", &y);
}
return 0;
}
If I input 4, shouldn't it take 4 more inputs? Instead it allows me to enter 5 integers! Tried it for other numbers too.
The format string in scanf works as follows (see http://www.cplusplus.com/reference/cstdio/scanf/)
[The format is a] C string that contains a sequence of characters that control how
characters extracted from the stream are treated:
Whitespace
character: the function will read and ignore any whitespace characters
encountered before the next non-whitespace character ...
In both your scanf() you have a newline. Therefore the first time you hit the enter key, it is ignored by scanf.
Some of the answers are telling you to modify the loop... this is incorrect, your loop is fine. it is the above that's causing you the headache. Try the following:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int T, y, z;
scanf ("%i", &T);
printf("Count is= %d\n", T);
for (T; T > 0 ; --T)
{
printf("T= %d\n", T);
scanf ("%i", &y);
}
return 0;
}
EDIT: Thank you to Daniel Fischer for his comment about flushing stdin, which I have now removed. Found this explanation (Using fflush(stdin)).
Just get rid of \n from your scanf