Can't set value of structure variable - c

I have a structure defined in quaternions.c
typedef struct quaternion{
double arr[4];
} quaternion;
with header file
#ifndef QUATERNIONS_H
#define QUATERNIONS_H
typedef struct quaternion{
double arr[4];
} quaternion;
#endif
Since this is my first time using C structures, I tried testing it out.
#include <stdio.h>
#include "quaternions.h"
int main(){
quaternion a;
a.arr[1]=2.5;
printf("%d\n",a.arr[1]);
return 0;
}
As far as I can tell, what I'm doing is almost identical to this article. However, when I compile and run this, it prints a random gibberish number. What am I doing wrong?

The correct printf conversion format specifier for a double is %f, not %d. See the documentation for that function for further information.
You should change the line
printf("%d\n",a.arr[1]);
to:
printf("%f\n",a.arr[1]);
By using the wrong conversion format specifier, your program is invoking undefined behavior. This explains why your program is printing "random gibberish" instead of the desired output.
Most good compilers will warn you if you use the wrong conversion format specifier. If your compiler doesn't warn you, then I suggest that you make sure that you have all warnings enabled. See this question for further information:
Why should I always enable compiler warnings?

Related

ctime returns NULL randomly

I am using ctime. However it always returns NULL. So it cores on sprintf line. It worked earlier. So not sure why it is randomly returning NULL?
I have the following code snippet:
int main()
{
char avp_val[50];
uint32_t date_value=1477069401;
sprintf(avp_val,"%s",ctime((time_t*)(&date_value)));
return;
}
Don't cast a pointer to uint32_t to a time_t. Use an actual time_t, so on systems with 64 bit time_t ctime isn't reading four bytes of garbage as part of the epoch time:
int main()
{
char avp_val[50];
time_t date_value=1477069401;
sprintf(avp_val,"%s",ctime(&date_value));
// Or, because it's what you're doing anyway, skip sprintf:
// strcpy(avp_val, ctime(&date_value));
return 0;
}
Casting to (time_t*) to silence compiler warnings silenced the warnings, it didn't fix the problem.
Well, your code lacks a bunch of include files:
#include <stdlib.h> /* for the types you use below, like uint32_t */
#include <stdio.h> /* for a prototype for sprintf, which you use below */
#include <time.h> /* for a prototype for ctime() see NOTE 1 */
You must also take into account that casting must be done with data values, not with pointers, as casting a pointer only bypasses the compiler type checking system and makes your code more error prone. In this case you conversion from uint32_t * to time_t * is too dangerous if both types happen to have different sizes, as you'll be cutting the value using only half the bits required. This is something knows as Undefined Behaviour and you should avoid it.
You also have to return an explicit value from main. It's a compile error not to do so, so your example cannot execute, because it does not compile (and so, you cannot receive NULL from ctime(3))
By the way, I tried your code with uint32_t date_value in a mac OS/X and it printed the right value of time, so probably time_t is a 32 bit value, but you had better to use a time_t as it is defined by that reason.
NOTE 1
The most important in this case is the prototype of ctime(), which returns a pointer to char and without a prototype, the compiler assumes it returns an int. At least, in 64bit platforms, both types are different sizes, and cannot be passed this way.
Please, always post a Complete, minimum, verifiable example, as you can hide the exact source of the error by editing your example to be shown.

How to assign a float value using GMP library in C?

I'm trying to learn how to use the GMP library in C by just writing a simple program to add some floating point numbers together, but at runtime it complains:
GNU MP: Cannot allocate memory (size=140735132293330)
Aborted (core dumped)
Here is the code:
#include <gmp.h>
#include <stdio.h>
int main(){
mpf_set_default_prec(64);
mpf_t sum;
mpf_init(sum);
mpf_set_ui(sum,0);
unsigned int i = 0;
while (i < 4) {
mpf_add_ui(sum,sum,i);
i++;
}
mpf_out_str(stdout,10,sum);
printf ("\n");
mpf_clear(sum);
}
I was able to do this with just the GMP mpz functions without issue, but when I try this with floats I'm stuck. The documentation doesn't really show any real examples for float functions so maybe I'm initializing or assigning the values incorrectly.
From the documentation,
it is a good idea to include stdio.h before gmp.h, since that will allow gmp.h to define prototypes for these functions
This way you get an error because you are calling the function with the wrong number of arguments. The reason you are not getting any warning for the lack of declaration is because mpf_out_str is a macro, defined in gmp.h which on your machine is installed in /usr/include and thus considered a system header, so the warning is disabled (use -Wsystem-headers to see it). This feels like a misfeature in gcc...
You must have not checked your compiler warnings properly, but the simple error is that you're calling mpf_out_str with the wrong number of arguments, which you can look up in the documentation:
size_t mpf_out_str (FILE *stream, int base, size_t n_digits, const mpf_t op)
// ^^^^^^^^^^^^^^^^

Array subscript has type 'char' warning is showed without using arrays

Hi I got this weird warning in this simple code that leaves me completely confused. I searched trough the page and I see that this is a warning to alert users to avoid using chars as index of matrix because they can be signned, but obviously this is not the case.
Here is the code:
#include <stdio.h>
#include <ctype.h>
int main() {
char c='t';
if (isspace(c)==0)
printf ("%c is not a space",c);
return (EXIT_SUCCESS);
}
my question is what is the reason of the warning? is it related with the fact that isspace expects an int as argument?
a warning to alert users to avoid using chars as index of matrix because they can be signned, but obviously this is not the case
Actually, it is the case ... what you see is not what the compiler sees.
is it related with the fact that isspace expects an int as argument?
Yes; isspace is a macro which (in your compiler implementation) accesses an array ... take a look at your ctype.h or ask your compiler to expand macros (e.g., gcc -E) and you will see the array access.
To avoid the warning, use
if (!isspace((unsigned char)c))

c sscanf and SCNu64 compile error

I don't understand the below error message when I compile this code. I couldn't find out what wrong with it.
Description Resource Path Location
Type expected ‘)’ before ‘SCNu64’.
#include <inttypes.h>
int calc_rate(uint64_t *rate, char val[], char mult[]) {
int rc = sscanf(val, "%" SCNu64 "%2s", rate, mult);
}
If you have both <inttypes.h> and <stdio.h> included, then the code fragment shown compiles cleanly. (You can't call sscanf() legally unless there's a prototype in scope.) That means the problem is in the code prior to what you are showing. Or it means that your compiler doesn't provide support for exactly 64-bit types, which is rather unlikely unless you're on a relatively obscure mainframe, or you aren't compiling in C99 or C11 mode.

why is strtof is always evaluating to HUGE_VAL?

What could be the issue here? It doesn't matter what number I choose for str, it is always 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
char *str = "2.6";
printf("%f\n", strtof(str, (char**)NULL));
//prints 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
whole program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *str = "2.6";
printf("%f\n", strtof(str, NULL));
return 1;
}
compile with -Wall:
test4.c:7: warning: implicit declaration of function âstrtofâ
What platform are you building for/on? The warning that you say is being emitted:
test4.c:7: warning: implicit declaration of function âstrtofâ
indicates that the compiler doesn't know that strtof() returns a float, so it's going to push an int to the printf() call instead of a double. strtof() is normally declared in stdlib.h, which you're including. But it wasn't a standard function until C99, so the exact compiler platform (and configuration/options you're using) may affect whether it's being made available or not.
strtof is defined in C99 only. It may be that passing the option -std=c99 to the compiler will fix it since default GCC (-std=gnu89) includes only a few C99 features.
Another option is to use the C89-kosher strtod. Which is probably the better option in the long run, anyways. (When do you need singles except in exceptional circumstances?)
Perhaps you've forgotten to include the correct header(s)?
#include <stdlib.h>
#include <stdio.h>
int main() {
printf("%f\n", strtof("2.6", NULL));
return 0;
}
produces:
2.600000
for me...
Given your warnings, you should try adding -std=c99 to get the C99 standard definitions from the header. By default it will assume that the return value is an int and then try to convert that to a float. This will obviously be wrong. Alternatively you could simply supply your own, correct declaration for strtof().
As the others have said, you need -std=c99. But you can also use strtod() which is string to double, and you don't need -std=c99 for that.
I was having problems with strtof() on CentOS 5.5 with glibc 2.5 unless I used -std=c99, but strtod() worked perfectly.

Resources