Anomalous scanf behaviour in C - c

I am trying to run the following code in C:
#include <stdio.h>
#include <stdint.h>
void main(){
int firstNum = 5;
int16_t secondNum;
printf("Please enter the first number: ");
scanf("%d", &firstNum);
printf("Please enter the second number: ");
scanf("%d", &secondNum);
printf("%d %d\n", firstNum, secondNum);
}
And the output I am getting is as follows:
Please enter the first number: 13
Please enter the second number: 4
0 4
--------------------------------
Process exited after 1.877 seconds with return value 4
Press any key to continue . . .
Why is that so?
My IDE is Dev-C++. Compiler is TDM-GCC 4.9.2 64-bit Release. Program name is TestBit.c (if that is relevant?).
Note: When I change the line int16_t secondNum; to int secondNum;, the program works as intended.

The proper specifier for int16_t secondNum is from <inttypes.h>
// scanf("%d", &secondNum);
scanf("%" SCNd16, &secondNum);
Better code would check the return value.
if (scanf("%" SCNd16, &secondNum) == 1) {
Success();
}

An int16_t is not the same thing as an int; so passing a pointer to one via scanf and pretending it is an int pointer can yield unexpected behaviour; thus your question.
Replace int16_t with int and your program works. For followup read the C Programming Language specification of types and what they mean.

Try changing to: scanf("%hd", &secondNum);
%d is a 4-byte data specifier, int16_t is actually only 2 bytes.
More references: https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=vs-2019

Related

C programming scanf assistance

I am attempting to build a form/gpa calculator for class, but when entering the amount of classes using scanf, the output is 6,487,576 regardless of what I enter.
int main()
{
int opt;
int c;
printf("*******************************\n");
printf("** Fanshawe Grade Calculator **\n");
printf("*******************************\n");
printf("Please Choose an Option:\n");
printf("[1] Enter Your Marks\n");
printf("[2] Quit\n");
scanf("%d", &opt);
switch(opt) {
case 1 :
printf("********************************************************\n");
printf("** Enter Your Marks For Your Courses (Up to 10 Only): **\n");
printf("********************************************************\n");
scanf("%i", &c);
printf("You Have Entered %i Classes!\n", &c);
/*int i;
for(i=1;i=c;i++) {
printf("Enter Your Mark for Class #%i\n", &i);
}*/
break;
case 2 :
printf("GoodBye!");
exit(0);
break;
}
return 0;
}
Help please!
When you use %i with scanf(), it can allow you to input hexadecimal and octal numbers as well (this isn't an issue as explained here).
However, you shouldn't use & while using printf() as it'll display the memory location of the variable instead of the value stored in it.
Try this:
case 1 :
printf("********************************************************\n");
printf("** Enter Your Marks For Your Courses (Up to 10 Only): **\n");
printf("********************************************************\n");
scanf("%d", &c);
printf("You Have Entered %d Classes!\n", c);
break;
printf("You Have Entered %i Classes!\n", &c) outputs the address of the variable c (&c takes the address), i.e. it outputs the number of the memory cell. Since you want to pass the value of the variable you should not use the operator of taking address of a variable &.
printf("You Have Entered %i Classes!\n", c);
There are two problems here. First, you need to include the following headers:
#include <stdio.h> // declares functions like printf and scanf
#include <stdlib.h> // declares functions like exit
If you don't include these headers, then the compiler does not know how to execute them or their exact formats. When you attempt to compile, the warnings will not be helpful. There are a few good websites for this; just search something like "c exit()" in Google and it will tell you which headers you need in the future. When I compiled this code, I used gcc main.c -Wall which forces all warnings to be displayed.
Secondly, you use the address of c in both cases. When you go to print the value of c, you are actually printing the address of c, not the value. scanf() takes the address(es) of the variables to store values in, but printf() takes the variables themselves. The code should look more like this:
scanf("%i", &c);
printf("You Have Entered %i Classes!\n", c);
It is also always a good idea to initialize your variables. This way, you know when something is assigned improperly, or not assigned at all. I forgot to assign my variables for a while, and when compiled on another machine, it didn't work. This is because different machines will initialize variables differently. Just change the code to the following:
int opt = 0;
int c = 0;

scanf function not working

I've had this problem with a couple of programs now, and I can not figure out why this keeps happening. This is my code:
#include <stdio.h>
#include <math.h>
int main(void){
double x = 0;
while(x <= 0){
printf("Enter a digit greater than 0.\n");
scanf("%lf", &x);
}
printf("%lf", &x);
}
and the output is:
Enter a digit greater than 0.
4
0.000000
please help
Use the following code
#include <stdio.h>
#include <math.h>
int main(void){
double x = 0;
while(x <= 0){
printf("Enter a digit greater than 0.\n");
scanf("%lf", &x);
}
printf("%lf", x);
}
You are using
printf("%lf", &x);
But the correct syntax to print value of x is:
printf("%lf", x);
Check the working code https://ideone.com/lpdlmX
First off,
printf ("%lf", &x);
will try to print the address of x rather than its value, and this is clearly into undefined behaviour territory(a). A half-decent compiler should warn you about this such as, with gcc:
program.c: In function 'main':
program.c:13: warning: format '%lf' expects argument of type
'double', but argument 2 has type 'double *' [-Wformat=]
printf ("%lf\n", &x);
^
Secondly, the normal printf specifier for double is %f rather than %lf. You can use the latter since the standard states it has no effect on certain data types but it's a bit of a waste doing so.
So what you need is actually:
printf ("%f", x);
The general rule is that you pass addresses to scanf because it needs to populate the objects at those addresses. For printf, you just pass the object itself (yes, even if the data is a pointer that you want printed as a pointer rather than pointing the object being pointed to).
And, finally, to make your code more robust, you would be wise to detect a problem with scanf since, it there's a problem with the input that leaves x set to zero, the program will continuously try to read that input, resulting in an infinite loop.
So a good starting point, taking all those comments into consideration, would be:
#include <stdio.h>
#include <math.h>
int main (void) {
double x = 0;
while (x <= 0) {
printf ("Enter a digit greater than 0.\n");
if (scanf ("%lf", &x) != 1) {
printf ("Invalid input\n");
return 1;
}
}
printf ("%f\n", x);
return 0;
}
(a) Specifically, from ISO C11 7.21.6.1 /9:
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
Always always check the return of scanf, that being said, you printf ("%f", x); -- there is no &x and no need for %lf, printf %f format specifiers prints doubles. (however it is required when using scanf -- man scanf and man printf are your friends)
Putting it altogether, you could safely take input as follows:
#include <stdio.h>
int main (void) {
double x = 0;
while(x <= 0){
printf ("Enter a digit greater than 0.\n");
if (scanf ("%lf", &x) != 1) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
}
printf ("%f", x);
}
note: you must exit the loop on conversion failure (or empty stdin before attempting to take input again -- or your input will fail) Reason: on a failed conversion - no additional characters are read leaving the characters causing the failure just waiting to bite you again on the next go-round...

Wrong output in calculating average program

For years, I don't do anything in C and now I can't do simple things, I was accustomed to cin and cout and now Java. I was trying to make a simple program to calculate the average X amount of exams notes. The output are "random numbers" and checking to interrupt the program occurs before entering a note. Why is that?
#include <stdio.h>
int main(void) {
int numeroDeNotas;
float nota = 0.0;
float notaAuxiliar = 0.0;
char continuar;
int media;
do{
printf("Enter the exam grade\n");
scanf("%f", &notaAuxiliar);
nota += (int) notaAuxiliar;
numeroDeNotas++;
printf("Do you want to continue? Enter n if you want to stop\n");
scanf("%c", &continuar);
}while(continuar != 'n');
printf("%d\n\n", nota);
printf("%d\n\n", numeroDeNotas);
media = nota/numeroDeNotas;
printf("Average grade: %d", media);
return 0;
}
nota is a float, but you are using %d format code to print it. %d expects an int; you need %f to print floating point numbers.
C's standard I/O formatting is definitely not typesafe. When you provide a format code, you have to make sure the corresponding argument has the right type. However, if you had compiled with the -Wall option (at least, with gcc or clang), the compiler would have warned you.
Also, scanf("%c", &continuar); reads a single character without skipping whitespace, which will be the character immediately following the number read by scanf("%f", &notaAuxiliar);. That character is most likely a newline. You need to skip whitespace before reading the y or n, so you could use:
scanf(" %c", &continuar);
numeroDeNotas was declared with a variable type - float. So you can't use %d later in your code when writing a printf statement.
numeroDeNotas
variable is declared but no where initialized. and you are incrementing in do while loop.
media = nota/numeroDeNotas;
printf("Average grade: %d", media);
and you are using garbage value to calculate media which is undefined output. initialize numeroDeNotas to zero.

Undesired Output - Printing out Two Numbers

I'm fairly new to C programming, so I figured I'd try writing a simple program to
print two int numbers. I prompt the user for both numbers, and then just print both using printf
However, upon running the program, I get a result which is really bizarre.
For instance...
Enter first int: 5
Enter second int: 3
First int: 2130567168
Second int: 2686756
My code is below...
#include <stdio.h>
int main()
{
int x, y;
printf("Enter first number: ");
scanf("%i", x);
printf("Enter second number: ");
scanf("%i", y);
printf("%i\n%i%\n",x,y);
return 0;
}
This is because you forgot the & in the scanf statement. So change it to this:
scanf("%i", &y);
scanf("%i", &x);
//^ See here
Also you have one % too much in your printf statement. Because % is for format specifiers, so if you want to print the symbol % you have to write it 2 times:
printf("%i\n%i%\n",x,y);
//^ Is a format specifier so if you want to print the symbol, write it 2 times
Side note:
If you use the specifier %i in your scanf statement and you enter something like this: 035 the output would become 29, because it would be interpreted as octal number. So if you don't want that you can change the specifier to %d and 035 becomes 35
Change the code like this.
scanf("%i", &y);
scanf("%i", &x);
While storing the value to the variable you have to give the address of that variable. If you are using the arrays you don't need to give that. In printf statement , use the needed specifiers.
printf("%i\n%i\n",x,y);
You forgot the '&' in the scanf statement:
scanf("%i", &y);
scanf("%i", &x);
//^ this

how to convert char to int

I'm trying to write a short program were:
#include <stdio.h>
void main()
{
char=a,b,c;
printf("please place 3 numbers:\n");
scanf("%c%c%c", &a,&b,&c);
}
The exercise I'm trying to solve is how to change the char to int so if I write in a the number 3, I will get the number 3 Printed.
at this point I'm only getting the value.
I would appreciate any help.
The answer depends somewhat on what you can assume about the character set. If it's something like ASCII (or really, any character set that includes the digits in sequential order), you just need to offset the character value by the value of the character 0:
int aValue = a - '0';
I'm sure that C# provides better ways to do what you're trying to do, though. For example, see this question for some examples of converting strings to integer values.
First of all your syntax need some checking
You should know that you declare a variable this way (a char in this example):
char a;
If you want to declare multiple variables of the same type in a row you do :
char a, b, c;
If you want to assign a value to a declared variable :
a = '3';
Now to print a char using printf (man printf is a must read, more infos are in coreutils) :
printf("%c", a);
If you want to get the char from the command line, I recommand you to use getchar() (man getchar) instead of scanf because if suits better what you are trying to achieve and doesn't require you to use a syntax in scanf that I am sure you don't fully understand yet.
Your question is incredibly light on details, so here are several options:
#include <stdio.h>
int main()
{
char a,b,c;
printf("please place 3 numbers:\n");
scanf("%c%c%c", &a,&b,&c);
printf("Printing ints (auto-promotion): %d %d %d\n", a, b, c);
printf("Printing ints (explicit-promotion): %d %d %d\n", (int)a, (int)b, (int)c);
printf("Printing digits: %d %d %d\n", a-0x30, b-0x30, c-0x30);
return 0;
}
If the input is 123,
I expect the output to be:
Printing ints (auto-promotion): 49 50 51
Printing ints (explicit-promotion): 49 50 51
Printing digits: 1 2 3
Some things I fixed along the way.
main should return an int, not be void.
char=a,b,c; is a syntax error. You meant char a,b,c;
added a return 0; at the end of main.
You question is not quite understandable. Still I'll try to help. I think that what you want is to store an integer value in the char variable. You can do so by using the following code:
#include<stdio.h>
void main()
{
char a,b,c;
printf("Enter three numbers:\n");
scanf(" %c %c %c",&a,&b,&c); //notice the spaces between %c
}
Or if you want to enter a character and print its ASCII value, you can use the following code:
#include<stdio.h>
#include<conio.h>
void main()
{
char a,b,c;
printf("Enter three characters:\n");
scanf(" %c %c %c",&a,&b,&c);
printf("Entered values: %d %d %d",a,b,c);
getch();
}

Resources