Functions and arguments giving error - c

The result of this code down below should be 30, however when compiled and run this is giving me the following result
the result of 2358968 and 0 is 4200271, a , b , result
I
don't understand when I have no variables of that value how could the result be like that?
#include<stdio.h>
#include<conio.h>
void add( int , int );
int main(){
add(10,20);
getch();
return 0 ;
}
void add(int a, int b){
int result = a + b;
printf("the result of the %d and %d is %d, a, b, result");
}

In your code,
printf("the result of the %d and %d is %d, a, b, result");
should be
printf("the result of the %d and %d is %d\n", a, b, result);
^
|
//format string ends here
// arguments for format specifiers are meant to be
// supplied as different arguments to `printf()`, not as a part of <format> string itself
From the man page of printf()
int printf(const char *format, ...);
and
The functions in the printf() family produce output according to a format ....
So basically your code should be
printf("<format>", var1, var2,....);
The supplied variables are not part of the format.
The problem in your code were missing variables (arguments) for supplied format specifiers. As per the C11 standard , chapter 7.21.6.1, paragraph 2
[...] If there are insufficient arguments for the format, the behavior is
undefined. [...]
So, your code produces undefined behaviour printning out some junk value.
Moral of the Story : If you had enabled compiler warnings, you compiler should warn you about missing (mismatch) agruments in printf(). So, always enable warnings.

You have closed the " at the end of the line. and in the printf function you have specified the %d So the %d will not have the variable to point and fetch the value.
You will get the warning message that %d expects a matching int
It will have the garbage value in that position, So it is printing some value.

Sourav Ghosh answered to most of your questions; he rightly suggested to enable all warnings when compiling. If your compiler is (notably on Linux) some recent GCC or Clang/LLVM pass -Wall -Wextra -g to the gcc or clang command (to get nearly all warnings, some extra ones, and debug information). Others compiler options (-fsanitize=address etc etc...) and other tools (the gdb debugger, the valgrind tool, strace, ...) might be useful too!
I dont understand when I have no variables of that value how could the
result be like that?
Because you have encountered undefined behavior. Read much more about it (in particular Lattner's blog on What Every C Programmer should know about Undefined Behavior), and work hard to always avoid it in all cases. Be aware that with UB, your (or any other) program might seems to work while in fact it has some undefined behavior.
The particular garbage (or apparently random) values that are printed : might not be reproducible, and can be explained only by diving into every implementation details, including looking into the machine code generated by your particular compiler and inspecting some machine state (register values); concretely the printf implementation on your system is probably using some stdarg(3) things and fetching some values from uninitialized memory or register which happens to have some previous "garbage" value (at the machine level).
See also this answer (and many others) about undefined behavior. Work hard to always avoid it.
Remember that when coding (even in C) you are ultimately coding for some virtual or abstract machine which is not the real computer. Even if writing all the software levels from the operating system kernel included - that would take you many dozens of years at least -, you are coding for some specified abstraction and you have to ignore some misbehavior of your computer (e.g. if it breaks, get some cosmic rays, etc etc...) outside of these abstractions. The C99 or C11 programming language standard specification (a technical document of several hundred pages in English), with the POSIX 2008 operating system specification, are useful abstractions to code software for.

printf statement is the reason for undesired output,
printf("the result of the %d and %d is %d, a, b, result");
There is no arguments specified for format specifier, the position of " has to be changed.
the statement should be like this
printf("the result of the %d and %d is %d", a, b, result);
In your printf statement it was taking garbage value since no arguments were specified there for %d.

printf("the result of the %d and %d is %d, a, b, result");
it has to be
printf("the result of the %d and %d is %d", a, b, result);
it will read and assign the %d value from left to write.
printf returns number of characters

Related

How to swallow a parameter in printf in C

Say I have a printf with many parameters:
printf("%d %d %d %d", A, B, C, D);
For some reason I would like one parameter to no longer be printed, but still be listed in the parameter list (for instance for visual reason, or maybe it's a function call with a necessary side effect, etc).
Can I replace %d with a conversion letter with no output ? I don't recall such a conversion letter. Or maybe playing with the flags...?
[Edit] I just noticed that scanf has something similar (but the reverse): an assignment suppression flag '*'. for instance sscanf("123 345 678", "%i %*i %i", &a, &b) will lead to a=123 b=678
If you for some reason must change these on the fly, then keep things simple:
printf("%d ", A);
printf("%d ", B);
if(c)
printf("%d ", C);
printf("%d ", D);
You can suppress Strings (char*) arguments by specifying zero-width.
However, I know of no way to suppress numeric (int and float) values.
int main(void) {
int a=1;
char* b="hello"; // Gets Suppressed
int c=3;
printf("%d %.0s %d\n", a, b, c); // .0 means "zero-width"
return 0;
}
First of all, I agree with Radosław Cybulski's comment: Relying on side-effects is a dangerous thing. So please don't do that.
As for suppressing the printing of a parameter I think there is no built-in placeholder for that and it would probably be better to just comment out the whole printf statement and add the version without the suppressed parameter below it.
With that said there are two(not very elegant) solutions I could come up with that does something similar to what you'd like to achieve:
Method1
You could create a macro like this:
#define SUPPRESS_PRINT(x) "\0"/*x*/
This will replace the parameter with a null terminator character.
Then you can use it in your printf statement like this:
printf("%d %d %s %d", A, B, SUPPRESS_PRINT(C), D);
Notice that the placeholder for C (i.e. the suppressed parameter) had to be changed to %s that is a null terminated string in order for this "trick" to yield the desired result.
Correction:
I've enhanced the above solution thanks to jhx's awesome suggestion in the comments. Using sequential evaluation possible side-effects won't be omitted. The revised macro would look like this:
#define SUPPRESS_PRINTF_ARG(x) ((x), "")
Usage would stay the same as described above.
Method2
There is yet another, possibly simpler, solution. It is a POSIX feature not a C99 one but it would work in most scenarios I assume. It is to use a parameter field in each format placeholder. Something like this:
printf("%1$d %2$d %3$d %4$d", A, B, C, D);
Then if you'd want to omit let's say parameter C from being printed you could just delete %3$d from the format string. Thus getting this:
printf("%1$d %2$d %4$d", A, B, C, D);
This might be the simplest way to go about it.
Working principle: The parameter field ties the format placeholder to a given parameter using its ordinal number. Thus even if you remove one the rest will still print correctly.
Note: As far as my testing goes this method does not omit side-effects!

printf() still works although lacking of parameter

This program:
#include <stdio.h>
#include <conio.h>
int main()
{
printf("%d %d %d",1) ;
getch();
return 0;
}
gives me result 1 0 0 instead of warning or error or 1
Could you please tell me the logic behind it ?
I'm using Visual Studio 2010 to compile this code.
This is undefined behavior and not something you should rely on. While using printf () if sufficient and appropriately matching arguments are not provided, like in your case printf("%d %d %d",1), C does not define what should happen in that case and so the behavior is not standard or defined.
It is possible that this could cause your program to crash (if the next memory addresses from where printf () read values are not accessible or non-existant).
With printf(), if insufficient matching arguments are not provided, the result is undefined behavior.
C does not define what should happen in this case.
... If there are insufficient arguments for the format, the behavior is
undefined. ... C11 §7.21.6.1 2
OP's code obviously printed 2 additional int with the value of 0. Why 0 today - look at the compiled assembly language. Might another compilation of the code has the same result - maybe - maybe not. It is not defined by the language.
printf doesn't care if there aren't enough arguments. "doesn't care" means that it doesn't actually check the number of items in the format list to make sure that a sufficient number of arguments have been specified.
if there are not enough arguments, printf will just access computer memory (the memory that would have been used, had sufficient arguments been specified) and use whatever data is there.
this is "undefined behavior" and the results will vary. it's possible that this could cause your program to crash (if the memory at the location is inaccessible or non-existent).
you'll find that this sort of thing is very common in languages like C, where you can do things should be considered "invalid" but that are simply accepted by the compiler.

MinGW with GCC on Windows misreporting numeric values

For some reason, whenever I use a numeric value in my compiler set-up (MinGW on Windows, using a CMD prompt to compile and run), it completely misreports numbers in the program.
Code example:
//C hello world example
#include <stdio.h>
int main()
{
int value;
value = 10;
printf("The number is %d \n"), value;
int value2;
value2 = -100;
printf("The number is %d \n"), value2;
return 0;
}
Cf. screenshot of output.
value and value2 have to be passed as arguments, i.e. within the parantheses. Change it to the following:
printf("The number is %d \n", value);
And do similarly with value2.
Once again, this shows that compiling with -Wall and -pedantic switches on is useful. GCC most likely would have issued a warning message.
By saying
printf("The number is %d \n"), value;
you're somehow making (mis)use of the "comma operator" , so no syntax error is produced. Your print statement is considered as
printf("The number is %d \n");
and value si executed as a void expression.
Now, printf() being a variadic function, it does not check for the required number of arguments for supplied format specifiers (by default), but, point to note, as per the required format for printf(), you're essentially missing out the operand to the %d format specifier. This in turn invokes undefined behaviour.
As the standard mandates
If there are insufficient arguments for the format, the behavior is
undefined.
The correct syntax will be
printf("The number is %d \n", value);
where the value will be the argument to %d format specifier.
Moral of the story: Enable compiler warning and pay heed to them.
Note: Some suggestions,
The recommended signature of main() is int main(int argc, char**argv), or, atleast int main(void).
Try to get into a habit of defining and initialize any variable at the same time. Will save you from the danger of ending up using uninitialized value (local variables) at later part.

strtof() producing weird results in C

first of all, compiling with flags -Wall, -ansi, -pedantic. no warnings or errors. and no debugging is helping.
basically my code is working fine however returning very weird and unexpected results when I turn a token from a string to a float using strtof()
the section of code below is:
printf("token is %s\n", token);
newstockdata->unitPrice = strtof(token, NULL);
printf("price is %d\n", newstockdata->unitPrice);
newstockdata is allocated to the correct size: unitPrice is a float variable: the first printf statement prints "150.00": the second printf statement prints "0" but after a few iterations it returns a really long consistent number. any help please?
The problem is here, assuming that unitPrice is a float:
printf("price is %d\n", newstockdata->unitPrice);
To print a float you must use the %f specifier. Otherwise, it is undefined behaviour and anything could happen.
A possible explanation of the changing values you see might be that your system passes floats in a different register to ints. The printf receiving %d is looking in a register that is never set, so you are seeing whatever value was left over from some previous operation.
This is actually pretty common, here is an example - %esi is used for the int, and %xmm0 is used for the floating-point value.
You have to handle overflow cases. After calling strtof() check errno for overflow. If you think the values could be very long, you can use double or long double.

Why does the strange value come out with an unnecessary % conversion in the code in C language?

I started learning programming only few days ago, so basically I have no knowledge.
I'm starting with C, and I wrote a very simple code which is:
int main (int argc, const char * argv[])
{
printf("%d + %d", 1 + 3);
return 0;
}
with the code above, I got the value of 4 + 1606416608 and later found that the return value is wrong because I put more %d than necessary. Then my question is, how did that strange value actually come out? If anyone knows, please help me. Thank you!!
You know what you did wrong already, so to explain what your particular implementation of C probably did:
When you call printf, a new stack frame is pushed to the call stack. The call stack is a last in first out structure with one 'frame' per called function. So if main called logStuff which called printf then three consecutive frames would be for main, then logStuff, then printf. When printf returns, it's frame is removed from the structure and execution continues with logStuff.
So a frame usually contains at least the parameters passed to the function and storage for local variables. Those things may be one and the same, it's implementation dependant.
With a variadic function like printf there's a stream of unnamed parameters. The bit patterns will be put into an appropriate place in the frame. But C is not a reflective language. Each bit patten doesn't inherently have a meaning: any one could be an integer, a float, or anything else. It also isn't a language that invests in bounds checking. You're trusted to write code that acts correctly.
printf determines the types and number of unnamed parameters from the string. So if you've given it false information, it will interpret the bit patterns with something other than their correct meaning and it may think there are fewer or more than are really there.
You told it there were more. So what probably happened was that the parameters were in the equivalent of an array and it read a value from beyond the end of the array. As it's all implementation dependent, that value may have been meant to represent anything. It could be the address of the caller. It could be uninitialised storage for another local variable. It could be bookkeeping. It could be the format string, incorrectly interpreted as an integer.
What it isn't is any reliable value. It may not even always be safe to read.
You are in undefined behavior land... you are telling a variadic function that you have 2 int sized params, then you only supply one, you are leaking something from the stack.
1) %d is a format specifier, it tells the compiler how you want to access the value stored at a particular location.(here as an integer)
2) For every format specifier you need to provide a corresponding variable or a value, otherwise at runtime you will get "garbage" i.e. some random value.
Example :
int main()
{
int a = 65;
printf("\na = %d", a); // here the value stored in a is accessed as an integer.
printf("\na = %c", a); // the value inside a is accessed as a character.
return 0;
}
In the above example '%d' in the first printf statement tells the compiler that the value stored in the variable a is to be accessed as an integer. (o/p - 65)
In the second printf statement '%c' is used to access the same variable as a character.(o/p - A)
Your code expects two numerical parameters to be printed, and you're giving it one.
Expected:
printf("%d + %d", <some_num>, <another_num>);
You're giving it:
printf("%d + %d", <some_num>);
Where <some_num> is what 1+3 evaluates to. The function expects another argument, but receives garbage instead.
What you should do is
printf("%d + %d = %d", 1, 3, 1+3);

Resources