Casting to struct type

This is what Im trying to achieve if possible but am getting garbage values in struct array members elements.

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

struct _time{
  char _second[3];
  char _minute[3];
  char _hour[3];
  char _monthDay[3];
  char _month[4];
  char _year[3];
};
struct _time get_time(void);
void prefix_shm(char *a);
int main(void){

struct _time my_time=get_time();
printf("seconds=%s\n",my_time._second);
return 0;
}

struct _time get_time(void){

char _seconds[3]={0};
char _minute[3]={0};
char _hour[3]={0};
char _monthDay[4]={0};
char _month[3]={0};
char _year[3]={0};

strcpy(_seconds,"1");
//prefix_shm(_seconds);
strcpy(_minute,"1");
//prefix_shm(_minute);
strcpy(_hour,"1");
strcpy(_monthDay,"1");
strcpy(_month,"1");
strcpy(_year,"1");

  return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

};

void prefix_shm(char *a) {
  if (strlen(a) == 1 ) {
    a[1] = a[0];
    a[0] = '0';
  }
}

If I will make a struct inside a function and return it its working.

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

struct _time{
  char _second[3];
  char _minute[3];
  char _hour[3];
  char _monthDay[3];
  char _month[4];
  char _year[3];
};
struct _time get_time(void);
void prefix_shm(char *a);
int main(void){

struct _time my_time=get_time();
printf("seconds=%s\n",my_time._second);
return 0;
}

struct _time get_time(void){

struct _time my_time={{0},{0},{0},{0},{0},{0}};

  strcpy(my_time._second,"2");
  prefix_shm(my_time._second);
  strcpy(my_time._minute,"2");
  prefix_shm(my_time._minute);
  strcpy(my_time._hour,"3");
  strcpy(my_time._monthDay,"4");
  strcpy(my_time._month,"5");
  strcpy(my_time._year,"6");

  return my_time;

};


void prefix_shm(char *a) {
  if (strlen(a) == 1 ) {
    a[1] = a[0];
    a[0] = '0';
  }
}

Because first option is working with struct containing integers:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

struct _time{
  int a;
  int b;
};
struct _time get_time(void);
void prefix_shm(char *a);
int main(void){

struct _time my_time=get_time();
printf("seconds=%d\n",my_time.a);
return 0;
}

struct _time get_time(void){

  return (struct _time){1,2};

};


void prefix_shm(char *a) {
  if (strlen(a) == 1 ) {
    a[1] = a[0];
    a[0] = '0';
  }
}

Is there way to make first option working or I have to declare struct same type in the function like in 2-nd code?
Thanks.

not sure what you're trying to do

you can statically initialize a data structure

struct _time  t1 = {
    "30",
    "59",
    "23",
    "31",
    "Jan",
    "20",
};

not sure why you maintain the datetime as strings and not integers

why do you prefix the elements of you struct with an underscore ("_")?

That was just an example to show the problem.

For ease of compilation and debugging I made data static.

will truncate this code to make it easier to explain:

struct _time{
  int second;
  int minute;
};

struct _time get_time(void);

int main(void){

struct _time my_time=get_time();

printf("seconds=%d\n",my_time.second);

return 0;

}

struct _time get_time(void){

  return (struct _time){1,2};

};

so this snipped compiles and function converts and returns struct as expected. So in struct my_time members second and minute have values 1 and 2 respectively.

now same approach but for char arrays this time.

struct _time{
  char _second[3];
  char _minute[3];
  char _hour[3];
  char _monthDay[3];
  char _month[4];
  char _year[3];
};
struct _time get_time(void);

int main(void){

struct _time my_time=get_time();

printf("seconds=%s\n",my_time._second);

return 0;
}

struct _time get_time(void){

char _seconds[3]={0};
char _minute[3]={0};
char _hour[3]={0};
char _monthDay[4]={0};
char _month[3]={0};
char _year[3]={0};

strcpy(_seconds,"1");
strcpy(_minute,"1");
strcpy(_hour,"1");
strcpy(_monthDay,"1");
strcpy(_month,"1");
strcpy(_year,"1");

  return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

};

second one has a problem which I cant figure out yet.

the return statement in getTime () didn't work with an initialization statement containing braces

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct _time{
    char _second[3];
    char _minute[3];
    char _hour[3];
    char _monthDay[3];
    char _month[4];
    char _year[3];
};

struct _time  t1 = {
    "30",
    "59",
    "23",
    "31",
    "Jan",
    "20",
};

// -----------------------------------------------------------------------------
void
disp (
    struct _time t)
{
    printf (" %s %s %s", t._month, t._monthDay, t._year);
    printf (" %2s:%2s:%2s\n", t._hour, t._minute, t._second);
}

// -------------------------------------
struct _time
getTime (void)
{
    struct _time t = { "10", "29", "11", "15", "Mar", "19" };
    return t;
}

// -------------------------------------
int main(void){
    disp (t1);
 // struct _time my_time=get_time();
 // printf("seconds=%s\n",my_time._second);

    struct _time t2 = getTime();
    disp (t2);

    return 0;
}

output

 Jan 31 20 23:59:30
 Mar 15 19 11:29:10

surepic:
This is what Im trying to achieve if possible but am getting garbage values in struct array members elements.

#include <stdio.h>

#include <stdlib.h>
#include <strings.h>

struct _time{
 char _second[3];
 char _minute[3];
 char _hour[3];
 char _monthDay[3];
 char _month[4];
 char _year[3];
};
struct _time get_time(void);
void prefix_shm(char *a);
int main(void){

struct _time my_time=get_time();
printf("seconds=%s\n",my_time._second);
return 0;
}

struct _time get_time(void){

char _seconds[3]={0};
char _minute[3]={;
char _monthDay[4]={0};
char _month[3]={0};0};
char _hour[3]={0}
char _year[3]={0};

strcpy(_seconds,"1");
//prefix_shm(_seconds);
strcpy(_minute,"1");
//prefix_shm(_minute);
strcpy(_hour,"1");
strcpy(_monthDay,"1");
strcpy(_month,"1");
strcpy(_year,"1");

return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

};

void prefix_shm(char *a) {
 if (strlen(a) == 1 ) {
   a[1] = a[0];
   a[0] = '0';
 }
}

This code does not compile for me.

To initialize your struct with array, you must define a constructor which take arrays as arguments:

struct _time
{
  _time(char* inSecond)
  {
    //copy values here
  } 
  char _second[3];
};

struct _time get_time(void){

  char _seconds[3]={0};
  return (struct _time){_seconds};

};

Arduino_new I cant compile your code …

the only solution so far is the second code in first post....i.e. declaring struct inside the function and then returning it.

What are you using to compile your code?

surepic:
the only solution so far is the second code in first post....i.e. declaring struct inside the function and then returning it.

Why is that a problem?

OP, what's the benefit of attempting to return the structure from the function versus, say, using a pointer to reference the variable, something like:

typedef struct s_time
{
    int second;
    int minute;
    
}sTime_t;


void setup( void )
{
    sTime_t theTime = {5, 10};    
    sTime_t *ptheTime;
        
    Serial.begin(115200);
    
    ptheTime = (sTime_t *)&theTime;

    Serial.println( "Before: " );
    Serial.print( "Second: " ); Serial.println( theTime.second );
    Serial.print( "Minute: " ); Serial.println( theTime.minute );
    
    getTime( ptheTime );
    
    Serial.println( "After : " );
    Serial.print( "Second: " ); Serial.println( theTime.second );
    Serial.print( "Minute: " ); Serial.println( theTime.minute );
        
}//setup

void loop( void )
{
}//loop

void getTime( sTime_t *timestruct )
{
    timestruct->second = 1;
    timestruct->minute = 2;
        
}//getTime

Blackfin:
OP, what's the benefit of attempting to return the structure from the function versus, say, using a pointer to reference the variable, something like:

typedef struct s_time

{
   int second;
   int minute;
   
}sTime_t;

void setup( void )
{
   sTime_t theTime = {5, 10};    
   sTime_t *ptheTime;
       
   Serial.begin(115200);
   
   ptheTime = (sTime_t *)&theTime;

Serial.println( "Before: " );
   Serial.print( "Second: " ); Serial.println( theTime.second );
   Serial.print( "Minute: " ); Serial.println( theTime.minute );
   
   getTime( ptheTime );
   
   Serial.println( "After : " );
   Serial.print( "Second: " ); Serial.println( theTime.second );
   Serial.print( "Minute: " ); Serial.println( theTime.minute );
       
}//setup

void loop( void )
{
}//loop

void getTime( sTime_t *timestruct )
{
   timestruct->second = 1;
   timestruct->minute = 2;
       
}//getTime

Slightly different syntax, and a bit less setup, passing the structure to the function by reference:

typedef struct s_time
{
  int second;
  int minute;

} sTime_t;

void setup( void )
{
  sTime_t theTime = {5, 10};

  Serial.begin(115200);

  Serial.println( "Before: " );
  Serial.print( "Second: " ); Serial.println( theTime.second );
  Serial.print( "Minute: " ); Serial.println( theTime.minute );

  getTime( theTime );

  Serial.println( "After : " );
  Serial.print( "Second: " ); Serial.println( theTime.second );
  Serial.print( "Minute: " ); Serial.println( theTime.minute );

}//setup

void loop( void )
{
}//loop

void getTime( sTime_t &timestruct )
{
  timestruct.second = 1;
  timestruct.minute = 2;

}//getTime

Firstly thanks to everyone for contribution.

All given solutions are either passing struct to a function via pointer or copy....

While modifying one code which uses char array I tried to cast them to struct by changing return type of the function and giving it "values" to combine.

Its working if struct type has int members … which I showed in one of my previous posts with int second and int minute. I was able to combine them back to struct only in the return statement.

But same approach with char array isn't working.

@david_2018 I`m using mingw compiler.

struct _time{
  char _second[3];
  char _minute[3];
  char _hour[3];
  char _monthDay[3];
  char _month[4];
  char _year[3];
};

struct _time get_time(void){

char _seconds[3]={0};
char _minute[3]={0};
char _hour[3]={0};
char _monthDay[4]={0};
char _month[3]={0};
char _year[3]={0};

strcpy(_seconds,"1");
strcpy(_minute,"1");
strcpy(_hour,"1");
strcpy(_monthDay,"1");
strcpy(_month,"1");
strcpy(_year,"1");

  return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

};

return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

I would like to understand why I am not able to "combine" and cast this variables into struct _time type ? Not worried about workarounds but more whats wrong here in the last line.

surepic:
Firstly thanks to everyone for contribution.

All given solutions are either passing struct to a function via pointer or copy....

While modifying one code which uses char array I tried to cast them to struct by changing return type of the function and giving it "values" to combine.

Its working if struct type has int members … which I showed in one of my previous posts with int second and int minute. I was able to combine them back to struct only in the return statement.

But same approach with char array isn't working.

@david_2018 I`m using mingw compiler.

struct _time{

char _second[3];
  char _minute[3];
  char _hour[3];
  char _monthDay[3];
  char _month[4];
  char _year[3];
};

struct _time get_time(void){

char _seconds[3]={0};
char _minute[3]={0};
char _hour[3]={0};
char _monthDay[4]={0};
char _month[3]={0};
char _year[3]={0};

strcpy(_seconds,"1");
strcpy(_minute,"1");
strcpy(_hour,"1");
strcpy(_monthDay,"1");
strcpy(_month,"1");
strcpy(_year,"1");

return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

};




return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

I would like to understand why I am not able to "combine" and cast this variables into struct _time type ? Not worried about workarounds but more whats wrong here in the last line.

mingw is not a compiler.
Your code does not compiled because it is not legal to initialize an array with another array.
For

return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

this to compile, your struct must have appropriated constructors.

Compiler gcc from mingw toolset.

Compiler is compiling ok values were garbage but here I modified the code a little and it works. This is not the way that I gonna use it I already switched to using struct inside that function but about struct must have appropriated constructors :

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

struct _time{
  int _second[3];
  int _minute[3];
  int _hour[3];
  int _monthDay[3];
  int _month[4];
  int _year[3];
};
struct _time get_time(void);
void prefix_shm(char *a);
int main(void){

struct _time my_time=get_time();
printf("seconds=%d\n",my_time._second[0]);
printf("seconds=%d\n",my_time._second[1]);
printf("seconds=%d\n",my_time._second[2]);
return 0;
}

struct _time get_time(void){

int _seconds[3]={0};
int _minute[3]={0};
int _hour[3]={0};
int _monthDay[4]={0};
int _month[3]={0};
int _year[3]={0};

_seconds[0]=1;
_seconds[1]=2;
_seconds[2]=3;

  return (struct _time){{_seconds[0],_seconds[1],_seconds[2]},{_minute},{_hour},{_monthDay},{_month},{_year}};

};

compiles and runs ok.

surepic:
Compiler gcc from mingw toolset.
...
compiles and runs ok.

Because you compiled it with C and not C++.
These are warnings from your code:

gcc -o weird weird.c 
weird.c: In function ‘get_time’:
weird.c:38:64: warning: initialization of ‘int’ from ‘int *’ makes integer from pointer without a cast [-Wint-conversion]
   38 | return (struct _time){{_seconds[0],_seconds[1],_seconds[2]},{_minute},{_hour},{_monthDay},{_month},{_year}};
      |                                                              ^~~~~~~

weird.c:38:64: note: (near initialization for ‘(anonymous)._minute[0]’)
weird.c:38:74: warning: initialization of ‘int’ from ‘int *’ makes integer from pointer without a cast [-Wint-conversion]
   38 | ruct _time){{_seconds[0],_seconds[1],_seconds[2]},{_minute},{_hour},{_monthDay},{_month},{_year}};
      |                                                              ^~~~~

weird.c:38:74: note: (near initialization for ‘(anonymous)._hour[0]’)
weird.c:38:82: warning: initialization of ‘int’ from ‘int *’ makes integer from pointer without a cast [-Wint-conversion]
   38 | me){{_seconds[0],_seconds[1],_seconds[2]},{_minute},{_hour},{_monthDay},{_month},{_year}};
      |                                                              ^~~~~~~~~

weird.c:38:82: note: (near initialization for ‘(anonymous)._monthDay[0]’)
weird.c:38:94: warning: initialization of ‘int’ from ‘int *’ makes integer from pointer without a cast [-Wint-conversion]
   38 | ds[0],_seconds[1],_seconds[2]},{_minute},{_hour},{_monthDay},{_month},{_year}};
      |                                                               ^~~~~~

weird.c:38:94: note: (near initialization for ‘(anonymous)._month[0]’)
weird.c:38:103: warning: initialization of ‘int’ from ‘int *’ makes integer from pointer without a cast [-Wint-conversion]
   38 | ds[0],_seconds[1],_seconds[2]},{_minute},{_hour},{_monthDay},{_month},{_year}};
      |                                                                        ^~~~~

weird.c:38:103: note: (near initialization for ‘(anonymous)._year[0]’)

So _minute is stuffed into _minute[3] as first element, as a value of a pointer, which is why the value is garbage.

still having a hard time understanding what the problem is

All given solutions are either passing struct to a function via pointer or copy....

While returning the struct pushes 19 bytes on the stack that ends up getting copied to a struct you could have simply referenced to save cycles and not pushed the stack deeper towards the heap.

When you have loads of RAM it's no big deal. Uno has 2K.

  return (struct _time){{_seconds[0],_seconds[1],_seconds[2]},{_minute},{_hour},{_monthDay},{_month},{_year}};

That line gives me the creeping willies.
edit-add: I think I know at least partly why. It creates a local variable then -returns- that, or garbage from below the end of the stack, not so sure and can't test it right now.

works

struct _time
getTime (void)
{
    return (struct _time) { "10", "29", "11", "15", "Mar", "19" };
}

Then why its not working when you are passing 0 terminated char array? Exact same size so there is no overflow anywhere?

Char array[3]={0};
Strcpy(array,”12”);

And string literal “12” arent they exactly same ?

surepic:
Then why its not working when you are passing 0 terminated char array?

any string enclosed by quotes is terminated with a NULL (0).

following does not work for me. i think one explanation is that it can't be initialized the values at compile time.

   char _seconds[3]    = "12";
    char _minute[3]     = "58";
    char _hour[3]       = "07";
    char _monthDay[4]   = "09";
    char _month[3]      = "02";
    char _year[3]       = "19";
    return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};

still not exactly clear what you're looking for

gcjr:
any string enclosed by quotes is terminated with a NULL (0).

following does not work for me. i think one explanation is that it can't be initialized the values at compile time.

   char _seconds[3]    = "12";

char _minute[3]    = "58";
    char _hour[3]      = "07";
    char _monthDay[4]  = "09";
    char _month[3]      = "02";
    char _year[3]      = "19";
    return (struct _time){_seconds,_minute,_hour,_monthDay,_month,_year};




still not exactly clear what you're looking for

Might appear to work if you declare all the strings as static, as it is you are returning pointers to data that ceases to exist when you exit the function.