g_random_int() returns negative numbers - c

This is the documentation of g_random_int() function from GLib:
guint32 g_random_int (void);
Return a random guint32 equally distributed over the range [0..2^32-1].
But the following code returns negative numbers:
for (i=0; i< 10; ++i)
printf("Random: %d\n", g_random_int());
Something obvious that I am missing.

The problem is in your printf-format string.
%d is the format-specifier for signed integers.
You are effectively reading the unsigned integer as if it was signed.
Use %u instead :) Then your code becomes
for (i=0; i< 10; ++i)
printf("Random: %u\n", g_random_int());
Here is a reference for the various format-specifiers in C: http://www.cplusplus.com/reference/cstdio/printf/
EDIT
I believe this is the passage in the C99 standard that describes the case of undefined behavior for the formatted output-functions, that #12431234123412341234123 refers to:
In a call to one of the formatted output functions, a precision appears with a conversion specifier other than those described (7.19.6.1, 7.24.2.1).
.. or maybe it's this:
An invalid conversion specification is found in the format for one of the formatted input/output functions, or the strftime or wcsftime function (7.19.6.1, 7.19.6.2, 7.23.3.5, 7.24.2.1, 7.24.2.2, 7.24.5.1).
See this page for more cases that are undefined behavior: https://gist.github.com/Earnestly/7c903f481ff9d29a3dd1
EDIT2
See the comment section for a much more intelligent discussion of the issue.

Related

Am I using conversion specifiers wrong or something? scanf() isn't working in c

scanf() isnt working properly when I use the following lines of code in c:
double withdraw = 0;
scanf("%.2lf",&withdraw);
printf("\n\nWithdraw %.2lf?",&withdraw);
and this:
double withdraw = 0;
scanf("%.2lf",withdraw);
printf("\n\nWithdraw %.2lf?",withdraw);
and this:
double withdraw = 0;
scanf("%.2lf",&withdraw);
printf("\n\nWithdraw %.2lf?",withdraw);
and finally this:
double withdraw = 0;
scanf("%.2lf",withdraw);
printf("\n\nWithdraw %.2lf?",&withdraw);
input into scanf() is ALWAYS this:
1
output of withdraw is ALWAYS this:
0.00
Please help. This seems so crazy to me!
Yes, your code is wrong. You cannot use precisions (".<int>") with fscanf() family, that's invalid. This causes causes undefined behavior.
Quoting C11, chapter §7.21.6.2/p3, fscanf()
Each conversion specification is introduced by the character %.
After the %, the following appear in sequence:
— An optional assignment-suppressing character *.
— An optional decimal integer greater than zero that specifies the maximum field width
(in characters).
— An optional length modifier that specifies the size of the receiving object.
— A conversion specifier character that specifies the type of conversion to be applied.
and, p13
If a conversion specification is invalid, the behavior is undefined.
That said, do not use trial and error, undefined behaviors are tricky to catch and understand. read the manual pages for proper format specifier for any argument type.
As your compiler is telling you
warning: unknown conversion type character ‘.’ in format [-Wformat=]
So you cannot specify precision with this type of format specifier
The following could work.
#include <stdio.h>
#include <math.h>
int main()
{
double withdraw = 0;
scanf("%lf", &withdraw);
printf("\n\nWithdraw %.2lf?", withdraw);
return 0;
}

Why is printf() printing out in this code?

This simple code is puzzling me - I am deliberately printing out more integers than I passed to printf. I expected an error. I got weird numbers - where are they coming from?
#include <stdio.h>
/* learn arrays */
void main(){
int pout;
pout = 6;
printf("%i %i %i\n%i %i %i\n%i %i %i\n", pout);
}
One example of the output:
6 608728840 0
-885621664 -885543392 608728816
0 0 -889304251
The single digits do not change with repeated runs, but the large integers do.
It's one of printf string format vulnerability. You are trying to call more argument than there actually are, so printf takes whatever he can on the stack.
It was (and still is) very used to exploit programs into exploring stacks to access hidden information or bypass authentication for example.
Viewing the stack
printf ("%08x %08x %08x %08x %08x\n");
This
instructs the printf-function to retrieve five parameters from the
stack and display them as 8-digit padded hexadecimal numbers. So a
possible output may look like:
40012980 080628c4 bffff7a4 00000005 08059c04
See this for a more complete explanation.
Because it's undefined behavior. If the number of specifiers is larger than the number of matching parameters or their types are incompatible, the behavior is undefined.
This qoute is from the c11 standard draft
7.21.6.1 The fprintf function
The fprintf function writes output to the stream pointed to by stream, under control of the string pointed to by format that specifies how subsequent arguments are converted for output. If there are insufficient arguments for the format, the behavior is undefined. If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored. The fprintf function returns when the end of the format string is encountered.
If a conversion specification is invalid, the behavior is undefined.282) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
I highlighted the relevant parts making them bold.
The int reserves some RAM but you didn't wrote anything in so it shows you what numbers are random somewhere in your RAM

C function printf() limited in length?

Upon calling the sprintf function to format a string, something unexpected was printed
printf("%d;%s;%s;%d;%d;\n", ptr->programmaType, ptr->titel, ptr->zender, ptr->start, ptr->einde);
prints "0;Stargate;scifi;0;0;" while
printf("%d;", ptr->einde);
prints "42", which is the value of ptr->einde. I've also tried
printf("%d;%s;%s;%d;%d;", 0, "Stargate", "scifi", 0, 42);
which prints correctly, so I'm guessing the problem is related to the variables. Last thing I tried was
int bug = ptr->einde;
printf("%d;%s;%s;%d;%d;\n", ptr->programmaType, ptr->titel, ptr->zender, ptr->start, bug);
which also failed to print correctly... I have no idea what the hell is happening.
Note: ptr->start and ptr->einde are defined als time_t types, but seeing as printf works with a single argument I doubt that's a problem.
You said that ptr->start and ptr->einde are time_t type. This type is not not fully portable and can be any "integer or real-floating type", so it's possible that they are not being handled correctly on your system when you try to print them as int types.
Try casting it to something known and then printing:
printf("%d;%s;%s;%ld;%ld;\n", ptr->programmaType, ptr->titel,
ptr->zender, (long)ptr->start, (long)ptr->einde);
I guess your definition of ptr->einde is not of type int.
And you are using "%d" in the printf specifier which expects an int value.
Use the correct specifier for the correct type and printf behaves.
No printf is not limited in length, except in embedded implementations where it must be able to print at least 4095 chars.
time_t is probably a 64 bit integer value. The solution is to cast your variable to (uint64_t) and using PRIu64 format specifier.
printf("%d;%s;%s;%"PRIu64";%"PRIu64";\n",
ptr->programmaType,
ptr->titel, ptr->zender,
(uint64_t)ptr->start,
(uint64_t)ptr->einde);

int and char to float format specifier

I have the foll line of code.
int i =125;
char s[]="hello";
char c='z';
printf("%f",i);
printf("%f",c);
printf("%f",s);
output -936283178250000000000.000000 -936283178250000000000.000000 -936283178250000000000.000000 what does this mean??
It means you are using the incorrect formatting directives. Try this instead:
printf("%d", i);
printf("%c", c);
alternatively, cast your two values in i and c to float (but that doesn't make much sense, especially in the case of c), better to use the right formatting directives.
When you use the incorrect specifier, the behavior is undefined, which is what you are observing.
Where did you get %f from? If not mistaken %f is a C++ parameter for floating point numbers.
By you using:
int i =125;
char s[]="hello";
char c='z';
printf("%f",i);
printf("%f",c);
printf("%f",s);
You are telling the compiler that everything you are printing is a floating point number (a.k.a decimal), when in fact it should be
printf("%d",i);
printf("%c",c);
printf("%s",s);
Using a wrong format specifier in printf will result in undefined behavior. When I say undefined behavior, it can give an output but the output may vary from one C implementation to another. Usually this will result in a warning. GCC compiler will issue a warning for this.

What is the difference between %d and %*d in c language?

What is %*d ? I know that %d is used for integers, so I think %*d also must related to integer only? What is the purpose of it? What does it do?
int a=10,b=20;
printf("\n%d%d",a,b);
printf("\n%*d%*d",a,b);
Result is
10 20
1775 1775
The %*d in a printf allows you to use a variable to control the field width, along the lines of:
int wid = 4;
printf ("%*d\n", wid, 42);
which will give you:
..42
(with each of those . characters being a space). The * consumes one argument wid and the d consumes the 42.
The form you have, like:
printf ("%*d %*d\n", a, b);
is undefined behaviour as per the standard, since you should be providing four arguments after the format string, not two (and good compilers like gcc will tell you about this if you bump up the warning level). From C11 7.20.6 Formatted input/output functions:
If there are insufficient arguments for the format, the behavior is undefined.
It should be something like:
printf ("%*d %*d\n", 4, a, 4, b);
And the reason you're getting the weird output is due to that undefined behaviour. This excellent answer shows you the sort of things that can go wrong (and why) when you don't follow the rules, especially pertaining to this situation.
Now I wouldn't expect this to be a misalignment issue since you're using int for all data types but, as with all undefined behaviour, anything can happen.
When used with scanf() functions, it means that an integer is parsed, but the result is not stored anywhere.
When used with printf() functions, it means the width argument is specified by the next format argument.
The * is used as an indication that the width is passed as a parameter of printf
in "%*d", the first argument is defined as the total width of the output, the second argument is taken as normal integer.
for the below program
int x=6,p=10;
printf("%*d",x,p);
output: " 10"
the first argument ta passed for *, that defines the total width of the output... in this case, width is passed as 6. so the length of the entire output will be 5.
now to the number 10, two places are required (1 and 0, total 2). so remaining 5-2=3 empty string or '\0' or NULL character will be concatenated before the actual output

Resources