Incorrect result after adding days to date - c

Using below function, which simply adds days to date (yyyymmdd), works fine throughout years.
int dateplusdays(int datein, int days) {
int year, month, day;
int dateout;
struct tm date;
time_t secs;
year = (int)floor(datein / 10000.0);
month = (int)floor(datein / 100.0) - year * 100;
day = datein - month * 100 - year * 10000;
date.tm_sec = 0;
date.tm_min = 0;
date.tm_hour = 12;
date.tm_year = year - 1900;
date.tm_mon = month - 1;
date.tm_mday = day;
date.tm_isdst = -1;
secs = mktime(&date) + days * 86400;
date = *localtime(&secs);
dateout = (date.tm_year + 1900) * 10000 + (date.tm_mon + 1) * 100 + date.tm_mday;
return dateout;
}
I stress-tested from 1900 to 2100 using this test code. No errors!
for (i = 19000101; i < 21001231; i++) {
int a = dateplusdays(i, 0); // make date out of i
if (i == a) { // check for valid date
int b = dateplusdays(a, 1);
int c = dateplusdays(b, 1);
if (b == c)
printf("i:%d a:%d b:%d c:%d\n", i, a, b, c);
}
}
Now ... when changing date.tm_hour from 12 to 0, I get exactly 184 errors on very specific dates, spread completely irregularly throughout the range of years 1900-2100 (e.g. 30.10.2022 adding 1 day results in 30.10.2022).
i:19160930 a:19160930 b:19161001 c:19161001
i:19161001 a:19161001 b:19161001 c:19161001
...
i:20221029 a:20221029 b:20221030 c:20221030
i:20221030 a:20221030 b:20221030 c:20221030
...
i:20381030 a:20381030 b:20381031 c:20381031
i:20381031 a:20381031 b:20381031 c:20381031
On top, only months September-December are concerned.
geohei#vm92:~/Devel$ ./dateplusdays | cut -c7-8 | sort | uniq -c
47 09
131 10
6 11
What am I missing?

You are missing switches between winter and summer time — standard and daylight saving time, or whatever other jargon is used. The choice of 12:00:00 for the time of day was not accidental.
You should use date.tm_day = day + days; to get the right answer (instead of adding days * 86400). The mktime() function normalizes dates. Note that there are 82800 and 90000 seconds on some days because of the switch in time zone offset from UTC.
Side note: why on earth are you using floating point arithmetic instead of plain integer division?
Hmmm: I tried your code with the bare minimum extras (headers, an actual main() function) and only got output when I changed the 12 in the code to 0 — running on a MacBook Pro with macOS Big Sur 11.7.2.
The dates you quote are near the end of October, when the clocks "fall back". Daylight saving time was first introduced in 1918 in the USA, then stopped after 1921. It was reintroduced for one year in 1945, then 'permanently' in 1965. The rules changed in 1991 so the autumnal time switch changed from "last Sunday in October" to "first Sunday in November", so I see different values from you. (The rules for the springtime time switch also changed from "first Sunday in April" to "second Sunday in March" at the same time.) I'd guess you are living somewhere outside North America (or at least, outside the USA).
Here's some revised code, exploiting mktime()'s abilities, using midnight. It also formats the data using the ISO 8601 notation. However, it produces no output unless it is compiled with -DUSE_BROKEN_CODE as a compile-time option.
#include <stdio.h>
#include <time.h>
static int dateplusdays(int datein, int days)
{
struct tm date = { 0 };
int year = datein / 10000;
int month = (datein / 100) % 100;
int day = datein % 100;
date.tm_sec = 0;
date.tm_min = 0;
date.tm_hour = 0;
date.tm_year = year - 1900;
date.tm_mon = month - 1;
date.tm_isdst = -1;
#ifdef USE_BROKEN_CODE
date.tm_mday = day;
time_t secs = mktime(&date) + days * 86400;
#else
date.tm_mday = day + days;
time_t secs = mktime(&date);
#endif /* USE_BROKEN_CODE */
date = *localtime(&secs);
int dateout = (date.tm_year + 1900) * 10000 + (date.tm_mon + 1) * 100 + date.tm_mday;
return dateout;
}
static void print_date(int date)
{
printf("%.4d-%.2d-%.2d", date / 10000, (date / 100) % 100, date % 100);
}
int main(void)
{
for (int i = 19000101; i < 21001231; i++)
{
int a = dateplusdays(i, 0); // make date out of i
if (i == a) // check for valid date
{
int b = dateplusdays(a, 1);
int c = dateplusdays(b, 1);
if (b == c)
{
printf("i: %d a: ", i);
print_date(a);
printf(" b: ");
print_date(b);
printf(" c: ");
print_date(c);
putchar('\n');
}
}
}
return 0;
}
I live in Colorado, USA, so I get results like this from the program when compiled with the broken code active:
i: 19181026 a: 1918-10-26 b: 1918-10-27 c: 1918-10-27
i: 19181027 a: 1918-10-27 b: 1918-10-27 c: 1918-10-27
i: 19191025 a: 1919-10-25 b: 1919-10-26 c: 1919-10-26
i: 19201030 a: 1920-10-30 b: 1920-10-31 c: 1920-10-31
i: 19201031 a: 1920-10-31 b: 1920-10-31 c: 1920-10-31
i: 19210521 a: 1921-05-21 b: 1921-05-22 c: 1921-05-22
i: 19210522 a: 1921-05-22 b: 1921-05-22 c: 1921-05-22
i: 19450929 a: 1945-09-29 b: 1945-09-30 c: 1945-09-30
i: 19450930 a: 1945-09-30 b: 1945-09-30 c: 1945-09-30
i: 19651030 a: 1965-10-30 b: 1965-10-31 c: 1965-10-31
i: 19651031 a: 1965-10-31 b: 1965-10-31 c: 1965-10-31
i: 19661029 a: 1966-10-29 b: 1966-10-30 c: 1966-10-30
i: 19661030 a: 1966-10-30 b: 1966-10-30 c: 1966-10-30
…
i: 19881029 a: 1988-10-29 b: 1988-10-30 c: 1988-10-30
i: 19881030 a: 1988-10-30 b: 1988-10-30 c: 1988-10-30
i: 19891028 a: 1989-10-28 b: 1989-10-29 c: 1989-10-29
i: 19891029 a: 1989-10-29 b: 1989-10-29 c: 1989-10-29
i: 19901027 a: 1990-10-27 b: 1990-10-28 c: 1990-10-28
i: 19901028 a: 1990-10-28 b: 1990-10-28 c: 1990-10-28
i: 19911026 a: 1991-10-26 b: 1991-10-27 c: 1991-10-27
i: 19911027 a: 1991-10-27 b: 1991-10-27 c: 1991-10-27
i: 19921024 a: 1992-10-24 b: 1992-10-25 c: 1992-10-25
i: 19921025 a: 1992-10-25 b: 1992-10-25 c: 1992-10-25
…
i: 20201031 a: 2020-10-31 b: 2020-11-01 c: 2020-11-01
i: 20201101 a: 2020-11-01 b: 2020-11-01 c: 2020-11-01
i: 20211106 a: 2021-11-06 b: 2021-11-07 c: 2021-11-07
i: 20211107 a: 2021-11-07 b: 2021-11-07 c: 2021-11-07
i: 20221105 a: 2022-11-05 b: 2022-11-06 c: 2022-11-06
i: 20221106 a: 2022-11-06 b: 2022-11-06 c: 2022-11-06
…
i: 20371031 a: 2037-10-31 b: 2037-11-01 c: 2037-11-01
i: 20371101 a: 2037-11-01 b: 2037-11-01 c: 2037-11-01
i: 20381106 a: 2038-11-06 b: 2038-11-07 c: 2038-11-07
i: 20381107 a: 2038-11-07 b: 2038-11-07 c: 2038-11-07
i: 20391105 a: 2039-11-05 b: 2039-11-06 c: 2039-11-06
i: 20391106 a: 2039-11-06 b: 2039-11-06 c: 2039-11-06
…
i: 20981101 a: 2098-11-01 b: 2098-11-02 c: 2098-11-02
i: 20981102 a: 2098-11-02 b: 2098-11-02 c: 2098-11-02
i: 20991031 a: 2099-10-31 b: 2099-11-01 c: 2099-11-01
i: 20991101 a: 2099-11-01 b: 2099-11-01 c: 2099-11-01
i: 21001106 a: 2100-11-06 b: 2100-11-07 c: 2100-11-07
i: 21001107 a: 2100-11-07 b: 2100-11-07 c: 2100-11-07

Related

write iterative function to calculate a mathematics sequence

for a homework, I need to program two functions to calculate a same mathematics sequence, recursive and iterative version. I succeeded to program the recursive version, but I don't know how to realize the iterative version.
(It's the first time I program with C language.)
the recursive version :
float sequence(int n)
{
float x = 1.0;
if(n>=1)
{
float temp = sequence(n-1);
x = temp+1/temp;
}
return x;
}
if the code works efficiently, I must to find sequence(0) = 1, sequence(1) = 2, sequence(3) = 2.5, sequence(4) = 2.9,..., sequence(100) ~ 14.284066.
Also, according to my professor, it's necessary the code is enough optimized (time complexity?) and without obvious semantic problems (too easy to discover).
Could you help me to realize iterative version with any suggestions?
So, if this question has already been asked, I'm sorry, could you give me the link please.
else I thank you for your time,
Sincerely.
I made it out, apparently it's the Fractional Chromatic Number sequence.
#include <stdio.h>
double seqrec(unsigned n) {
if (n < 2) return 1;
double prev = seqrec(n - 1);
return prev + 1 / prev;
}
double seqiter(unsigned n) {
double numerator = 1, denominator = 1;
for (unsigned k = 2; k <= n; k++) {
double newnumerator = numerator*numerator + denominator*denominator;
denominator = numerator*denominator;
numerator = newnumerator;
// avoid nan, get numbers down to a reasonable level :-)
while (denominator > 2) {
numerator /= 2;
denominator /= 2;
}
}
return numerator / denominator;
}
int main(void) {
for (int k = 1; k < 49; k++) {
printf("%d ==> %f, %f\n", k, seqrec(k), seqiter(k));
}
}
With the following output
1 ==> 1.000000, 1.000000
2 ==> 2.000000, 2.000000
3 ==> 2.500000, 2.500000
4 ==> 2.900000, 2.900000
5 ==> 3.244828, 3.244828
6 ==> 3.553010, 3.553010
7 ==> 3.834462, 3.834462
8 ==> 4.095255, 4.095255
9 ==> 4.339440, 4.339440
10 ==> 4.569884, 4.569884
11 ==> 4.788708, 4.788708
12 ==> 4.997533, 4.997533
13 ==> 5.197631, 5.197631
14 ==> 5.390027, 5.390027
15 ==> 5.575555, 5.575555
16 ==> 5.754909, 5.754909
17 ==> 5.928674, 5.928674
18 ==> 6.097345, 6.097345
19 ==> 6.261351, 6.261351
20 ==> 6.421061, 6.421061
21 ==> 6.576799, 6.576799
22 ==> 6.728848, 6.728848
23 ==> 6.877462, 6.877462
24 ==> 7.022865, 7.022865
25 ==> 7.165257, 7.165257
26 ==> 7.304819, 7.304819
27 ==> 7.441715, 7.441715
28 ==> 7.576093, 7.576093
29 ==> 7.708087, 7.708087
30 ==> 7.837821, 7.837821
31 ==> 7.965407, 7.965407
32 ==> 8.090950, 8.090950
33 ==> 8.214545, 8.214545
34 ==> 8.336280, 8.336280
35 ==> 8.456238, 8.456238
36 ==> 8.574494, 8.574494
37 ==> 8.691119, 8.691119
38 ==> 8.806179, 8.806179
39 ==> 8.919735, 8.919735
40 ==> 9.031846, 9.031846
41 ==> 9.142565, 9.142565
42 ==> 9.251944, 9.251944
43 ==> 9.360029, 9.360029
44 ==> 9.466867, 9.466867
45 ==> 9.572498, 9.572498
46 ==> 9.676964, 9.676964
47 ==> 9.780302, 9.780302
48 ==> 9.882549, 9.882549
Your recursion works deconstructively, starting with n and working backwards with recursive calls until it gets to the base case. For the base case, it returns the known answer, and at each level above the base case it evaluates the equation using returned result.
For iteration, you want to work constructively from the base case up to n. At each iteration, the current value is used to update the result from the previous iteration.
You used the pseudocode tag, so I'm providing this in Ruby (which is practically pseudocode but can be run to check the answers). You can translate it to C for yourself to enforce your understanding.
def recursive(n)
return 1.0 if n < 2
x = recursive(n - 1)
return x + 1 / x
end
def iterative(n)
x = 1.0
if n > 1
(n - 1).times { x += 1.0 / x }
end
return x
end
# Test it out
(0..10000).each { |input| puts "#{recursive(input)}\t#{iterative(input)}"}
I've tested, and both of those return identical answers for n up to 10000.

Bisection method to find root of sin(x) in c recursively

I want to find the root of sin(x) function by approximating an interval [a,b] recursively, but my output is:
-0.350783
But I want to get
3.1415
This is my code so far
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double dicho(double a,double b)
{
double m=(a+b)/2;
double eps=0.000001;
if((b-a)>=eps)
{
if(abs(sin(0)-sin(m))<=eps){
return m;
}
if(sin(m)<0){
a=m;
}
if(sin(m)>0){
b=m;
}
dicho(a,b);
}
}
void main()
{
int a,b;
a=3;
b=4;
double res=sin(dicho(a,b));
printf("%lf\n",res);
}
Everything klutt said. But there's also a glitch in your algorithm. Namely in the [3, 4] interval the sine function is strictly decreasing and this breaks down your logic a little bit.
Reworking your dicho function something like this seems to work:
double dicho(double a,double b)
{
double m=(a+b)/2;
double eps=0.000001;
if((b-a)>=eps)
{
printf("a: %lf b: %lf, m: %lf diff: %lf\n",
a, b, m, sin(0) - sin(m));
if(fabs(sin(0)-sin(m)) <= eps){
return m;
}
if(sin(m) < 0){
b = m; // look in [a, (a+b)/2]
}
if(sin(m)>0){
a = m; // look in [[a+b]/2, b]
}
return dicho(a,b);
}
return m;
}
When running with this function you can see the solution actually converges towards pi:
a: 3.000000 b: 4.000000, m: 3.500000 diff: 0.350783
a: 3.000000 b: 3.500000, m: 3.250000 diff: 0.108195
a: 3.000000 b: 3.250000, m: 3.125000 diff: -0.016592
a: 3.125000 b: 3.250000, m: 3.187500 diff: 0.045891
a: 3.125000 b: 3.187500, m: 3.156250 diff: 0.014657
a: 3.125000 b: 3.156250, m: 3.140625 diff: -0.000968
a: 3.140625 b: 3.156250, m: 3.148438 diff: 0.006845
a: 3.140625 b: 3.148438, m: 3.144531 diff: 0.002939
a: 3.140625 b: 3.144531, m: 3.142578 diff: 0.000985
a: 3.140625 b: 3.142578, m: 3.141602 diff: 0.000009
a: 3.140625 b: 3.141602, m: 3.141113 diff: -0.000479
a: 3.141113 b: 3.141602, m: 3.141357 diff: -0.000235
a: 3.141357 b: 3.141602, m: 3.141479 diff: -0.000113
a: 3.141479 b: 3.141602, m: 3.141541 diff: -0.000052
a: 3.141541 b: 3.141602, m: 3.141571 diff: -0.000022
a: 3.141571 b: 3.141602, m: 3.141586 diff: -0.000006
a: 3.141586 b: 3.141602, m: 3.141594 diff: 0.000001
a: 3.141586 b: 3.141594, m: 3.141590 diff: -0.000003
a: 3.141590 b: 3.141594, m: 3.141592 diff: -0.000001
3.141592
But with your original recursion logic (use fabs instead of abs though):
a: 3.000000 b: 4.000000, m: 3.500000 diff: 0.350783
a: 3.500000 b: 4.000000, m: 3.750000 diff: 0.571561
a: 3.750000 b: 4.000000, m: 3.875000 diff: 0.669405
a: 3.875000 b: 4.000000, m: 3.937500 diff: 0.714499
a: 3.937500 b: 4.000000, m: 3.968750 diff: 0.736010
a: 3.968750 b: 4.000000, m: 3.984375 diff: 0.746497
a: 3.984375 b: 4.000000, m: 3.992188 diff: 0.751673
a: 3.992188 b: 4.000000, m: 3.996094 diff: 0.754243
a: 3.996094 b: 4.000000, m: 3.998047 diff: 0.755524
a: 3.998047 b: 4.000000, m: 3.999023 diff: 0.756164
a: 3.999023 b: 4.000000, m: 3.999512 diff: 0.756483
a: 3.999512 b: 4.000000, m: 3.999756 diff: 0.756643
a: 3.999756 b: 4.000000, m: 3.999878 diff: 0.756723
a: 3.999878 b: 4.000000, m: 3.999939 diff: 0.756763
a: 3.999939 b: 4.000000, m: 3.999969 diff: 0.756783
a: 3.999969 b: 4.000000, m: 3.999985 diff: 0.756793
a: 3.999985 b: 4.000000, m: 3.999992 diff: 0.756798
a: 3.999992 b: 4.000000, m: 3.999996 diff: 0.756800
a: 3.999996 b: 4.000000, m: 3.999998 diff: 0.756801
a: 3.999998 b: 4.000000, m: 3.999999 diff: 0.756802
4.000000
When compiling with -Wall -Wextra this code gives me three warnings.
$ gcc b.c -lm -Wall -Wextra
b.c: In function ‘dicho’:
b.c:12:12: warning: using integer absolute value function ‘abs’ when argument is of floating point type ‘double’ [-Wabsolute-value]
12 | if(abs(sin(0)-sin(m))<=eps){
| ^~~
b.c: At top level:
b.c:28:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
28 | void main()
| ^~~~
b.c: In function ‘dicho’:
b.c:26:1: warning: control reaches end of non-void function [-Wreturn-type]
26 | }
| ^
You need to:
Change the signature of main to int main()
Change abs to fabs
Make sure that the recursive function actually does return. For instance, the recursive call dicho(a,b); within the dicho function should be return dicho(a,b); Also, what happens if (b-a)<eps? You should return something there too.
What happens if sin(m) evaluates to 0? Then you would be stuck in an endless loop. Well, not really because fabs(sin(0)-sin(m))<=eps will catch that case, but were you really aware of that? ;)
This does not solve the issue with wrong output, but it is the minimum on your way to solving it.
You have some serious programming errors like using integer abs where you should use floating point fabs and missing return statements.
But the worst part is the algorithm is wrong. When the algorithm is wrong, it won't help to fix the programming errors. The program will still fail.
The main problem with your algorithm is that you assume that sin(a) is less than zero and that sin(b) is greater than zero. You can't just assume that!
You need to handle all cases - for instance:
if (sin(a) > 0 && sin(b) > 0)
{
// both greater than zero
// What to do now ??? Maybe there isn't a solution in this interval
}
if (sin(a) < 0 && sin(b) < 0)
{
// both less than zero
// What to do now ??? Maybe there isn't a solution in this interval
}
if (sin(a) > 0)
{
// sin(a) larger than sin(b)
// Do recursive call
return dicho(?, ?);
}
else
{
// sin(a) less than sin(b)
// Do recursive call
return dicho(?, ?);
}
But what to put into the recursive call ?
Your approach is to do
return dicho(a, (a+b)/2));
in one case and
return dicho((a+b)/2), b);
in the other.
But that will not work!
Assume the following:
sin(a) is less than zero
sin(b) is greater than zero
sin((a+b)/2) is greater than zero
In this case we can do:
option 1:
return dicho((a+b)/2), b); // very bad as both are now greater than zero
option 2:
return dicho(a, (a+b)/2)); // good! one negative and one positive
So from this you see that just cutting the interval in half isn't a good idea. You need to add code that checks whether sin at the middle point is less or greater than zero and then do the call for the correct sub-interval (depending on the value of sin(a) and sin(b))
Something like:
if (sin(a) > 0)
{
// sin(a) larger than sin(b)
if (sin((a+b)/2) > 0)
{
return dicho((a+b)/2, b);
}
return dicho(a, (a+b)/2);
}
else
{
// sin(a) less than sin(b)
.... similar to the aboove code
}
Putting all cases into a truth table is often very helpful. Like:
----------------------------------------------------------------------------------
fabs(sin(a)) < eps | | | return a;
----------------------------------------------------------------------------------
fabs(sin(b)) < eps | | | return b;
----------------------------------------------------------------------------------
sin(a) > 0 | sin(b) > 0 | | oh dear - bad
----------------------------------------------------------------------------------
sin(a) < 0 | sin(b) < 0 | | oh dear - bad
----------------------------------------------------------------------------------
sin(a) > 0 | sin(b) < 0 | sin((a+b)/2) > 0 | return dicho((a+b)/2), b);
----------------------------------------------------------------------------------
sin(a) > 0 | sin(b) < 0 | sin((a+b)/2) < 0 | return dicho(a, (a+b)/2));
----------------------------------------------------------------------------------
sin(a) < 0 | sin(b) > 0 | sin((a+b)/2) > 0 | return dicho(a, (a+b)/2));
----------------------------------------------------------------------------------
sin(a) < 0 | sin(b) > 0 | sin((a+b)/2) < 0 | return dicho((a+b)/2), b);
----------------------------------------------------------------------------------
clang is even more helpful, suggesting that you use fabs
so6.c:12:12: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value]
if(abs(sin(0)-sin(m))<=eps){
^
so6.c:12:12: note: use function 'fabs' instead
if(abs(sin(0)-sin(m))<=eps){
^~~
fabs
so6.c:25:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^

C - fscanf error with char *

I'm trying to read a txt file with this format:
8590 2 07 Goku
8591 2 07 Vegeta
6973 2 07 Picolo
5432 3 02 Jerez
6773 3 02 Sour
4689 4 03 Mosco
6981 5 06 Cabba
7891 5 06 Frost
The columns are: hp, universe color, universe number and name. What I do is this read the line and save the parameters in an array of structures called warrior with this format:
typedef struct Warrior{
int hp;
int color;
int universe;
char * name;
int posX;
int posY;
int ki;
} warrior;
warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){
warrior guerrero;
guerrero.hp = inHp;
guerrero.color = inColor;
guerrero.universe = inUniverse;
guerrero.name = inName;
guerrero.posX= 0;
guerrero.posY= 0;
guerrero.ki=0;
return guerrero;
}
The readFile code is:
warrior * readFile(char * nameFile, warrior * listGuerrero){
FILE * filePointer;
int sizeFile = 0, ch = 0;
int inHp, inColor, inUniverse;
char inName[50];
filePointer = fopen(nameFile, "r");
while(fscanf(filePointer, "%d %d %d %s\n", &inHp, &inColor, &inUniverse, inName) != EOF){
sizeFile ++;
}
rewind(filePointer);
listGuerrero = (warrior *)malloc(sizeFile*sizeof(warrior));
for(int k = 0; k < sizeFile; k++){
fscanf(filePointer, "%d %d %d %s\n", &inHp, &inColor, &inUniverse, &inName[0]);
listGuerrero[k] = createWarrior(inHp,inColor,inUniverse,inName);
printf("k: %d - HP: %d - Color: %d - Universo: %d - Nombre: %s \n", k, listGuerrero[k].hp, listGuerrero[k].color, listGuerrero[k].universe, listGuerrero[k].name);
}
fclose(filePointer);
return listGuerrero;
}
But for some reason I can't understand, the final list of warriors all have the same name like:
j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Frost
j: 1 - HP: 8591 - Color: 2 - Universo: 7 - Nombre: Frost
j: 2 - HP: 6973 - Color: 2 - Universo: 7 - Nombre: Frost
j: 3 - HP: 5432 - Color: 3 - Universo: 2 - Nombre: Frost
j: 4 - HP: 6773 - Color: 3 - Universo: 2 - Nombre: Frost
j: 5 - HP: 4689 - Color: 4 - Universo: 3 - Nombre: Frost
j: 6 - HP: 6981 - Color: 5 - Universo: 6 - Nombre: Frost
j: 7 - HP: 7891 - Color: 5 - Universo: 6 - Nombre: Frost
Is something wrong with the inName pointer?
When I debug, the first iteration prints:
j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Goku
And the second iteration prints:
j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Vegeta
j: 1 - HP: 8591 - Color: 2 - Universo: 7 - Nombre: Vegeta
and so on.
the problem is that you read the first name and after that for every warrior in the file you just set a pointer to that first name. For every element from your file you must allocate new memory for it's name (using malloc) and copy the new name into it( using strcpy). Because you declared the name char*
warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){
warrior guerrero;
guerrero.hp = inHp;
guerrero.color = inColor;
guerrero.universe = inUniverse;
guerrero.name = malloc(sizeof(char) * 30); // 30 is the length of the name
strcpy(guerrero.name,inName); // copy new name
guerrero.posX= 0;
guerrero.posY= 0;
guerrero.ki=0;
return guerrero;
}
There is another cool way to do it using strdup() which basically alocates new memory and copy the parameter string there ( but i've not tested this):
warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){
warrior guerrero;
guerrero.hp = inHp;
guerrero.color = inColor;
guerrero.universe = inUniverse;
guerrero.name = strdup(inName);
guerrero.posX= 0;
guerrero.posY= 0;
guerrero.ki=0;
return guerrero;
}
Don't forget:
#include <string.h>
#include <stdlib.h>
All of your input from scanf is written to the same memory location given for inName[50]. In each iterration you are overwritting the content, but assigning the same address to the guerrero.name. And when you print out, you get last entry printed.
You may try this:
warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){
...
guerrero.name = strdup(inName);
....
return guerrero;
}

Returning array in C: random errors, garbage values

I'm trying to get this to work but I keep getting really weird errors, sometimes it executes without error, sometimes I get memory access violation errors, 7 of the returned values are always garbage and there's a printf that the program won't work with for some reason. I'm not good with C so I haven't the slightest clue what is going on.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
int gen_bp() {
int min = 0;
int max = 3;
int r;
r = (rand() % (max + 1 - min)) + min;
return r;
}
int * gen_gene(int len) {
int a;
int * gene = malloc(len);
int bp;
srand( (unsigned)time( NULL ) );
for( a = 0; a < len; a = a + 1 ){
bp = gen_bp();
printf("value of a: %i\n", bp); //if i remove this line, it crashes?!
gene[a] = bp;
}
return gene;
}
int main()
{
char codons[4] = {'G','T','A','C'};
int genelen = 20;
int counter;
int * gene;
gene = gen_gene(genelen);
for( counter = 0; counter < genelen; counter++ ){
printf("%i value of a: %i\n", counter, gene[counter]);
}
free(gene);
return(0);
}
This is the output I get
value of a: 1
value of a: 1
value of a: 3
value of a: 0
value of a: 2
value of a: 1
value of a: 3
value of a: 3
value of a: 1
value of a: 2
value of a: 3
value of a: 0
value of a: 3
value of a: 1
value of a: 0
value of a: 2
value of a: 3
value of a: 2
value of a: 2
value of a: 0
0 value of a: 1
1 value of a: 1
2 value of a: 3
3 value of a: 0
4 value of a: 2
5 value of a: 1
6 value of a: 3
7 value of a: 3
8 value of a: 1
9 value of a: 2
10 value of a: 1635131449 // 10 to 16 are always garbage, and never change
11 value of a: 1702194273
12 value of a: 543584032
13 value of a: 891304545
14 value of a: 808661305
15 value of a: 892351281
16 value of a: 2570
17 value of a: 2
18 value of a: 2
19 value of a: 0
Sometimes it ends fine with 0 error, other times it crashes after the output. Absolutely not the slightest clue why.
You are reserving space for len bytes, but you want to reserve space for
int * gene = malloc(sizeof(int) * len);
or
int * gene = malloc(sizeof(*gene) * len);
And you forget to #include <time.h>
Using malloc directly is too error-prone; in your code you forgot to multiply with the element size.
Use a macro instead:
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof (ptr)[0])
int *gene;
NEW_ARRAY(gene, len);

Openmp reduction for loop errors?

This is testing part of the code:
float a = 0;
float b = 0;
int c = 0;
int d = 0;
#pragma omp parallel for schedule (dynamic, 1) reduction(+ : a, b, c, d)
for(i=0; i<100; i++) {
a +=1;
b +=1;
c +=1;
d +=1;
}
printf("a: %d, b: %d, c: %d, d: %d\n", a, b, c, d);
For some reasons my results are always:
a: 100, b: 100, c: 0, d: 202
a: 100, b: 100, c: 0, d: 202
a: 100, b: 100, c: 0, d: 202
a: 100, b: 100, c: 0, d: 202
a: 100, b: 100, c: 0, d: 202
a: 100, b: 100, c: 0, d: 202
a: 100, b: 100, c: 0, d: 202
Why aren't a, b, c, d all equal to 100?
You are using %d formats to print floating point numbers. That causes undefined behaviour. Use:
printf("a: %f, b: %f, c: %d, d: %d\n", a, b, c, d);
And you'll see you get the right answers.

Resources