[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 287
  • Last Modified:

Using structures to save data

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.
0
ambuli
Asked:
ambuli
  • 6
  • 6
  • 3
  • +3
3 Solutions
 
Jaime OlivaresSoftware ArchitectCommented:
you can use memcpy:

memcpy(&new_struct, &old_struct, sizeof(new_struct));
0
 
ambuliAuthor 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.

0
 
ambuliAuthor 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;
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
ambuliAuthor 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
0
 
Jaime OlivaresSoftware ArchitectCommented:
yes, it is enough.
0
 
ambuliAuthor 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;
0
 
Jaime OlivaresSoftware ArchitectCommented:
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.
0
 
SeanDurkinCommented:
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.
0
 
IchijoCommented:
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

0
 
evilrixSenior Software Engineer (Avast)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

0
 
evilrixSenior Software Engineer (Avast)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

0
 
evilrixSenior Software Engineer (Avast)Commented:
NB. You should be aware that a struct is technically not longer considered a POD type if you implement a non-trivial constructor.
0
 
evilrixSenior Software Engineer (Avast)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

0
 
jkrCommented:
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

0
 
evilrixSenior Software Engineer (Avast)Commented:
I'm sure that was already mentioned { http:#20764868 }
0
 
jkrCommented:
Sorry, I have to admit that I simply missed that. My fault, going over the comments too fast.
0
 
evilrixSenior Software Engineer (Avast)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.
0
 
ambuliAuthor Commented:
Thanks a lot for all your feedback.  
0
 
ambuliAuthor Commented:
Thank you.
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 6
  • 6
  • 3
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now