I have this piece of code to check whether second date is earlier than the first date the program works normally when I input these with this order without commas 9,9,2021 but when I do input 09 for the first input It skips the second input and directly jumps into the third input I can't figure out why this is the case since I am fairly new to C
#include <stdio.h>
// Array format [DD,MM,YYYY]
int date[3];
int secondDate[3];
// ANSI color codes
#define RED "\x1b[31m"
#define GREEN "\x1b[32m"
int main()
{
printf("Enter the day of first date: ");
scanf("%i", &date[0]);
printf("Enter the month of first date: ");
scanf("%i", &date[1]);
printf("Enter the year of first date: ");
scanf("%i", &date[2]);
printf("Enter the day of the second date: ");
scanf("%i", &secondDate[0]);
printf("Enter the month of the second date: ");
scanf("%i", &secondDate[1]);
printf("Enter the year of the second date: ");
scanf("%i", &secondDate[2]);
return 0;
}
The %i formar specifier is recognizing the number base prefixes (that is "0x" for hexadecimal, and '0' for octal). The '0' prefix is for octal. And 09 is an invalid octal, as octal numbers contain digits 0-7.
You can use the %d specifier instead of %i, which is only interpreting decimal numbers.
Related
This question already has answers here:
How to do scanf for single char in C [duplicate]
(11 answers)
The program doesn't stop on scanf("%c", &ch) line, why? [duplicate]
(2 answers)
Closed 2 years ago.
i am a beginner in C programming. I was learning about the user inputs. The following piece of code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char grade;
printf("Enter you grade: ");
scanf("%c", &grade);
printf("Your grade is %c.", grade);
return 0;
}
does what I intend it to do i.e.
ask for the grade
display the grade
But when I modify the code to the following :
#include <stdio.h>
#include <stdlib.h>
int main()
{
int age;
printf("Enter you age: ");
scanf("%d", &age);
printf("You are %d years old.\n", age);
printf("-----------------------------\n");
double gpa;
printf("Enter your GPA: ");
scanf("%lf", &gpa);
printf("Your GPA is %f. \n", gpa);
printf("-----------------------------\n");
char grade;
printf("Enter you grade: ");
scanf("%c", &grade);
printf("Your grade is %c.", grade);
return 0;
}
it does the following:
asks for the age
displays the age
asks for the gpa
displays gpa
asks for grade
it doesnt display grade.
The output looks like:
Enter you age: 45
You are 45 years old.
-----------------------------
Enter your GPA: 4
Your GPA is 4.000000.
-----------------------------
Enter you grade: Your grade is
.
please suggest me what I am doing wrong.
When you enter your age, this is what is in the input buffer just before the scanf(%d) starts retrieving characters:
45<newline>
The scan(%d) skips any white space in the buffer (there isn't any), reads the 45, but leaves the newline. Then when you enter your GPA, this is what is in the input buffer just before the scanf(%lf) starts retrieving characters:
<newline>4<newline>
The scan(%lf) skips any white space in the buffer (the newline), reads the 4, but again leaves the newline. In other words, the leading newline doesn't matter if your next next scanf also skips whitespace such as moving from the first entry to the second.
But scanf(%c) does not skip white space. It simply reads the next character, which is a newline:
<newline>A<newline>
That's why tour period appears on the following line, it has read a character, but that character was the newline rather than the grade.
Section 7.21.6.2 The fscanf function, in the ISO C11 standard, has this to say on the first step of processing a conversion specifier (my emphasis):
Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier.
A quick fix would be to manually skip whitespace yourself, something like:
printf("Enter your grade: ");
scanf(" %c", &grade);
printf("Your grade is %c.", grade);
as per that same section of the standard:
A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read.
Was working on a program that prompts a user to enter a phone number and than prints it out using . instead of - so and when I run it it doesn't even let me input anything it just runs and gives me random values. So here's a look at the full program.
int item_number, year, month, day, first, middle, last;
//float unit_price;
printf("Enter item number: ");
scanf("%d", &item_number);
printf("Enter unit price: ");
scanf("%f", &unit_price);
printf("Enter purchase date (mm/dd/yyyy): ");
scanf("%d /%d /%d", &month, &day, &year);
printf("Item\t\tUnit\t\tPurchase\n\t\tPrice\t\tDate");
printf("\n%d\t\t$%6.2f\t\t%.2d/%.2d/%.2d\n", item_number, unit_price, month, day, year);
//here is the code that gives me the problem explained above.
//also if i comment the code above it works.
printf("Enter phone number [(xxx) xxx-xxxx] : ");
scanf("(%d) %d - %d", &first, &middle, &last);
printf("You entered %d.%d.%d", first, middle, last);
The problem you have encountered, is probably one of the most common problems encountered by new C programmers -- the improper use of scanf. Specifically, when you attempt to read the telephone number, stdin contains, e.g.:
"\n(888) 555-1212"
(the '\n' the result of pressing Enter after (mm/dd/yyyy) is entered)
As a result, the input waiting in stdin does not match "(%d...", and a matching failure results. Why? There is a newline at the beginning of the characters in stdin. The "%d" format specifier (all numeric conversion specifiers) will skip leading whitespace.
However, the leading whitespace does not precede the integer, it precedes the "(" which is not skipped by your format string. With scanf, a " " (space) in the format string, will cause any number of whitespace characters to be skipped/discarded. So as BLUEPIXY correctly notes, you need to add the space before the "(" in the format string to have scanf ignore the '\n' waiting in stdin.
Beyond that, you make the same mistake and misuse of scanf that nearly all new C-programmers do -- failing to check the return. scanf returns the number of successful conversions that take place based on the conversion specifiers in the format string.
At minimum, you must check the return of scanf (and in fact on ALL USER INPUT functions) to provide minimal validation that you do in fact have valid input stored in your variables to proceed forward with in your code. If you fail to check the return, you can have no confidence that undefined behavior isn't being invoked from that point forward. So validate all user input.
A minimal rewrite of your code that puts those pieces together would be:
#include "stdio.h"
int main (void) {
int item_number, year, month, day, first, middle, last;
float unit_price;
printf("Enter item number: ");
if (scanf ("%d", &item_number) != 1) { /* validate item */
fprintf (stderr, "error: invalid input (item_number)\n");
return 1;
}
printf("Enter unit price: ");
if (scanf ("%f", &unit_price) != 1) { /* validate unit */
fprintf (stderr, "error: invalid input (unit_price)\n");
return 1;
}
printf("Enter purchase date (mm/dd/yyyy): ");
/* validate date */
if (scanf ("%d /%d /%d", &month, &day, &year) != 3) {
fprintf (stderr, "error: invalid input (mm/dd/yyyy)\n");
return 1;
}
printf ("\t\tUnit\t\tPurchase\nItem\t\tPrice\t\tDate");
printf ("\n%d\t\t$%6.2f\t\t%.2d/%.2d/%.2d\n",
item_number, unit_price, month, day, year);
printf ("Enter phone number [(xxx) xxx-xxxx] : ");
/* validate phone */
if (scanf (" (%d) %d - %d", &first, &middle, &last) != 3) {
fprintf (stderr, "error: invalid input [(xxx) xxx-xxxx]\n");
return 1;
}
printf ("You entered %d.%d.%d\n", first, middle, last);
return 0;
}
Example Use/Output
$ ./bin/scanf_phone
Enter item number: 3
Enter unit price: 19.95
Enter purchase date (mm/dd/yyyy): 03/01/2017
Unit Purchase
Item Price Date
3 $ 19.95 03/01/2017
Enter phone number [(xxx) xxx-xxxx] : (800) 555-1212
You entered 800.555.1212
(note I tweaked the format to put Item on the 2nd line...)
Look things over, and spend the time it takes to understand man 3 scanf. It is time well spent.
If you are using Xcode, then write your printf statements like so:
printf("Enter item number:\n");
Put a newline(\n) at the end.
I am very new to C programming. I was trying to use the scanf function to ask the user to enter a date and display it in the console. So wrote the following codes:
#include <stdio.h>
#include <stdlib.h>
int main() {
int date, month, year;
printf("Please enter the date in the form of dd/mm/yyyy: ");
scanf("%d/%d/%d", &date, &month, &year);
printf("the date you entered was: %d-%d-%d\n", date, month, year);
return 0;
}
But the output am getting is not in a proper format, for example, I type in "10-12-2016", but the result I get was "10-554502544-32766". Any idea guys? Thanks in advance.
In your scanf(), you have this format - %d/%d/%d but you are giving the input as 10-12-2016, so you are doing wrong!
Instead, you should give input as - 10/12/2016 and the %d/%d/%d part in scanf() will ignore the / part from the input.
I type in 10-12-2016, but the result I get was 10-554502544-32766. Any idea guys?
Yes, when you are giving 10-12-2016 as input, scanf() assigning only 10 to date variable but no value to the other variables. Since the other two variables month and year is uninitialized, you are getting garbage value (554502544 and 32766) when you print the value of variable month and year.
One way to check this: Just initialize the variable and then take input.
int date = 0, month = 0, year = 0;
scanf("%d/%d/%d", &date, &month, &year);
Now, if you give 10-12-2016 as input, you will get 10-0-0 as output. Hopefully you can understand what is actually happening!
scanf() is a fairly kludgy tool. It expects the format to be exactly as you specified and if it isn't you get weird behaviour.
You either need to enter the text exactly as specified (dd/mm/yy, not dd-mm-yy) or change how you go about things.
Consider having scanf() scan in a string that you then lex yourself to get the values you want - you can be much more tolerant of variances in the input that way, as well as be more proof against someone trying to break your program by deliberately giving it invalid input.
You need to check the return value from scanf - See the manual page
#include <stdio.h>
#include <stdlib.h>
int main() {
int date, month, year;
printf("Please enter the date in the form of dd/mm/yyyy: ");
if (scanf("%d/%d/%d", &date, &month, &year) == 3) {
printf("the date you entered was: %d-%d-%d\n", date, month, year);
} else {
printf("You have made an error\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
int date, month, year;
printf("Please enter the date in the form of dd press enter then enter mm then press enter then enter year then press enter.. ");
scanf("%d", &date);
scanf("%d", &month);
scanf("%d", &year);
printf("the date you entered was: %d/%d/%d\n", date, month, year);
return 0;
}
I'm trying to take the user input, which is a character string, and convert it to a float. In my case, gas keeps being printed as 55.000000 when the user enters 7 - I'd like it to be printed as 7.0.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
int main()
{
char gas_gallons;
float gas;
printf("Please enter the number of gallons of gasoline: ");
scanf("%c", &gas_gallons);
while (!isdigit(gas_gallons))
{
printf("\nYou need to enter a digit. Please enter the number of gallons of gasoline: ");
scanf("%c", &gas_gallons);
}
if (isdigit(gas_gallons))
{
printf("\nHello %c", gas_gallons);
gas = gas_gallons;
printf("\nHello f", gas);
}
return 0;
}
Why not do this? It's much simpler.
#include<stdio.h>
int main()
{
int gas;
printf("Please enter the number of gallons of gasoline.\n : ");
//use the %d specifier to get an integer. This is more direct.
//It will also allow the user to order more than 9 gallons of gas.
scanf("%d", &gas);
printf("\nHello %d", gas);//prints integer value of gas
//Using the .1f allows you to get one place beyond the decimal
//so you get the .0 after the integer entered.
printf("\nHello %.1f\n", (float) gas);//print floating point
return 0;
}
You said:
In my case, gas keeps being printed as 55.000000 when the user enters 7
When the user enters 7 as input the digit 7 is stored as the character in gas_gallons. The decimal value of the character 7 is 55 in ASCII encoding. You can see the decimal values of other characters in ASCII encoding at Wikipedia and many other places on the web.
When you use:
gas = gas_gallons;
the integer value of gas_gallons is, i.e. 55, is assigned to gas. That explains why you get 55.000000 as the output when you print gas.
You can fix the problem many ways. Here are a couple of suggestions.
Option 1
Convert the digit to a number by using:
gas = gas_gallons - '0';
Option 2
Discard the code to read the number of gallons of gasoline as a digit and converting the digit to a number. Using a digit is also limiting since you cannot have 10 or 12.5 as input.
Read the number of gallons of gasoline as a number directly. With this approach, your input can be a any floating point number that can be represented by a float.
#include <stdio.h>
int main()
{
float num_gallons;
while ( 1 )
{
printf("Please enter the number of gallons of gasoline: ");
// Read the number of gallons of gas.
// If reading is successful, break of the loop.
if (scanf("%f", &num_gallons) == 1 )
{
break;
}
// There was an error.
// Read and discard the rest of the line in the input
// stream.
scanf("%*[^\n]%*c");
printf("There was an error in reading the gallons of gasoline.\n");
}
printf("\nHello %f\n", num_gallons);
return 0;
}
The ASCII-characters '0'-'9' do not have the integer values 0-9. You can find the appropriate value by subtracting '0'.
To convert a string to float you can use atof (ASCII to float) function included in stdlib.h.
Here is the full declaration of this function: double atof(const char *str)
so you can do a simple cast
gas = (float) atof(gas_gallons);
I am trying to figure out why I can't get this to run properly. I just want four inputs from the user, and run the calculation at the end.
#include <stdio.h>
#include <math.h>
int main(){
double amount; /* amount on deposit */
double principal; /* what's the principal */
double rate; /* annual interest rate */
int year; /* year placeholder and no. of total years */
int yearNo;
printf("What is the principal? ");
scanf("%d", &principal);
printf("What is the rate (in decimal)? ");
scanf(" .2%d", &rate);
printf("What is the principal? ");
scanf(" %d", &principal);
printf("How many years? ");
scanf(" %d\n", yearNo);
printf("%4s%21s\n", "Year", "Amount on deposit");
/* calculate the amount on deposit for each of ten years */
for (year = 1; year <= yearNo; year++){
amount = principal * pow(1.0 + rate, year);
printf("%4d%21.2f\n", year, amount);
}
return 0;
}
It properly asks for the principal and rate, but then skips over the question about Principal and asks for years. Then it just sits there waiting for a "ghost" entry?
I've been reading that the scanf() adds some whitespace when hitting enter but thought the space before the %d would fix that?
I also saw you could add do { c=getchar(); } while ( c != '\n'); after each scanf but that seems to crash the program (I added int c = 0; to the beginning too).
Thanks for any help or ideas!
EDIT:
When I change the erroneous format specifier from:
scanf(" .2%d", &rate);
to:
scanf(" %d", &rate);
I then get a crash after entering my values.
.2%d is not a valid format string.
For a start, the % has to come first. In addition, if you're after a floating point value, d is not the right character - it's for integral values.
You should be using something like %f (you don't need width or precision modifiers).
On top of that, you've made a minor mistake of not using a pointer for one of your scanf calls:
scanf(" %d\n", yearNo);
That's probably going to cause a crash, and should be changed to:
scanf(" %d\n", &yearNo);
And, as a final suggestion, it's totally unnecessary to use whitespace before (or a newline after) %d or %f family of format specifiers. The scanner automatically skips whitespace before both of those.
So, the only two scanf format strings you need in this program are "%d" and "%lf" (f is for floats, lf is for doubles).