We help IT Professionals succeed at work.

Using structures to save data

ambuli
ambuli asked
on
Hi experts,

In the following code snippets,  I need to copy the old and new values of nameOne, nameTwo, nameThree.  It is done as below.  Somedata? are values copied from a database....


char new_nameOne[20];
char new_nameTwo[20];
char new_nameThree[20];

char old_nameOne[20];
char old_nameTwo[20];
char old_nameThree[20];

strcpy( new_nameOne, somedata1 );
strcpy( new_nameTwo, somedata2);
strcpy( new_nameThree, somedata3);

strcpy( old_nameOne, somedata4 );
strcpy( old_nameTwo, somedata5);
strcpy( old_nameThree, somedata6);

Now I have moved nameOne, nameTwo, and nameThreeinto a structure declared like below.

typedef struct{
char *nameOne;
char *nameTwo;
char *nameThree;
}name_structure;

name_structure new_struct, old_struct;

I want to use new_struct, and old_struct to save the values.  How can I do it.

Thanks.
Comment
Watch Question

Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
you can use memcpy:

memcpy(&new_struct, &old_struct, sizeof(new_struct));

Author

Commented:
Thank you.  But, I do not want to copy from one structure to the other.  What I want is to avoid some old code cluttered with many variables(more than 15) and to use structures to somehow get them organized.

Author

Commented:

I should have asked how to copy from a char string to structure field.

Should the only way is to have

structure{
char nameOne[20];
char nameTwo[20];
char nameThree[20];
} name_structure;

Author

Commented:
So, the only way to do this like below.  Is that right?

structure{
char nameOne[20];
char nameTwo[20];
char nameThree[20];
} name_structure;

name_structure new_struct, old_struct;

strcpy( new_struct.nameOne, somedata1);
strcpy(new_struct.nameTwo, somedata2)...etc
Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008

Commented:
yes, it is enough.

Author

Commented:
Hi,

I was confused why I cannot use the following structure.  Is it because it does not have any storage?

typedef struct{
char *nameOne;
char *nameTwo;
char *nameThree;
}name_structure;
Jaime OlivaresSoftware Architect
CERTIFIED EXPERT
Top Expert 2008
Commented:
as you mentioned, it doesn't have its own storage, just pointers.
Pointers should point to a previously existing data, this data should keep "alive" while struct is "alive", if not, the pointers will point to invalid data, causing an application exception.
In case you decide you use this way, it should be used as:
    new_struct.nameOne = somedata1;
instead of:
    strcpy( new_struct.nameOne, somedata1);

notice it is an assignation/pointing process, instead of a string copy process, because initially nameOne is not pointing to any valid buffer.
With pointers, you will have to dynamically allocate the storage, which would make the strings more accurately sized, as well as be resized without making a new structure. If you *know* your structure members' lengths will not be longer than 20, though, then there's not much use to using dynamic memory allocation, and you should go with character arrays, not pointers.

Commented:
How about:
using namespace std;
 
typedef struct{
    string nameOne;
    string nameTwo;
    string nameThree;
}name_structure;
 
name_structure new_struct, old_struct;
 
new_struct.nameOne = somedata1;
new_struct.nameTwo = somedata2;
new_struct.nameThree = somedata3;
 
old_struct.nameOne = somedata4;
old_struct.nameTwo = somedata5;
old_struct.nameThree = somedata6;

Open in new window

evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
If this is C++ code is being built with a C++ compiler (you've put it in the C++ zone) and assuming each struct has it's own storage then since every struct will have an implicit copy constructor, so you can just assign one to another.
struct name_structure
{
	char nameOne[20];
	char nameTwo[20];
	char nameThree[20];
};
 
 
int main()
{
	name_structure s1 = {
		{"field1"},
		{"field2"},
		{"field3"}
	};
 
	name_structure s2 = s1;
 
	return 0;
}

Open in new window

Senior Software Engineer (Avast)
CERTIFIED EXPERT
Commented:
If the original struct doesn't have storage (it is just pointers) and you want to perform a deep copy you can always implement your own copy contructor.
#include <string.h>
 
#define SIZEOF_(x)(sizeof(x)/sizeof(x[0]))
 
struct old_name_structure
{
	char * nameOne;
	char * nameTwo;
	char * nameThree;
};
 
struct new_name_structure
{
	new_name_structure(old_name_structure const & old)
	{
		memset(nameOne, 0, SIZEOF_(nameOne));
		memset(nameOne, 0, SIZEOF_(nameOne));
		memset(nameOne, 0, SIZEOF_(nameOne));
 
		strncpy(nameOne, old.nameOne, SIZEOF_(nameOne)-1);
		strncpy(nameTwo, old.nameTwo, SIZEOF_(nameTwo)-1);
		strncpy(nameThree, old.nameThree, SIZEOF_(nameThree)-1);
	}
 
	char nameOne[20];
	char nameTwo[20];
	char nameThree[20];
};
 
 
int main()
{
	old_name_structure s1 = {
		{"field1"},
		{"field2"},
		{"field3"}
	};
 
	new_name_structure s2 = s1;
 
	return 0;
}

Open in new window

evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
NB. You should be aware that a struct is technically not longer considered a POD type if you implement a non-trivial constructor.
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
Of course, if you do implement a copy constructor (technically it's not really a copy constructor since it's copying a different type than its own, but I use the term semantically rather than technically), you might as well implement an assignment operator too so then you'll have both copy and assignment semantics from old to new.
#include <string.h>
 
#define SIZEOF_(x)(sizeof(x)/sizeof(x[0]))
 
struct old_name_structure
{
	char * nameOne;
	char * nameTwo;
	char * nameThree;
};
 
struct new_name_structure
{
	new_name_structure()
	{
		memset(nameOne, 0, SIZEOF_(nameOne));
		memset(nameOne, 0, SIZEOF_(nameOne));
		memset(nameOne, 0, SIZEOF_(nameOne));
	}
 
	new_name_structure(old_name_structure const & old)
	{
		*this = old;
	}
 
	new_name_structure & operator=(old_name_structure const & old)
	{
		*this = new_name_structure();
 
		strncpy(nameOne, old.nameOne, SIZEOF_(nameOne)-1);
		strncpy(nameTwo, old.nameTwo, SIZEOF_(nameTwo)-1);
		strncpy(nameThree, old.nameThree, SIZEOF_(nameThree)-1);
 
		return *this;
	}
 
	char nameOne[20];
	char nameTwo[20];
	char nameThree[20];
};
 
 
int main()
{
	old_name_structure s1 = {
		{"old_field1"},
		{"old_field2"},
		{"old_field3"}
	};
 
	new_name_structure s2;
 
	s2 = s1;
 
	return 0;
}

Open in new window

jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
A simple way - using the automatisms of C++ structs and classes - would be to transform them into 'std::string' storage, which only required using '=' to assing values and saves you all the copy stuff. That way (and using the compiler-generatoed default copy constructors and assignment operators), you can just
#include <string>
// *avoid* using 'using namespace std;' in header files
 
typedef struct{
std::string nameOne;
std::string nameTwo;
std::string nameThree;
}name_structure;
 
//...
 
name_structure new_struct, old_struct;
 
old_struct.nameOne = somedata1 ;
old_struct.nameTwo = somedata2 ;
old_struct.nameThree = somedata3 ;
 
new_struct = old_struct; // can be as simple as that

Open in new window

evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
I'm sure that was already mentioned { http:#20764868 }
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Sorry, I have to admit that I simply missed that. My fault, going over the comments too fast.
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
>> Sorry, I have to admit that I simply missed that
It happens :)

>> Um, I see that you defined a copy constructor...
Me? I didn't do anything with std::string. My examples are predicated on the members of the struct being already defined by the question. The code I referred to was posted by @Ichijo and that contains no explicit copy constructor and is almost identical to your own.

>> so I won't delete my comment, which I was about to do right now.
I don't think that is necessary... no one else without admin rights could do that.

Author

Commented:
Thanks a lot for all your feedback.  

Author

Commented:
Thank you.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.