Reputation: 862
I have a char array and I want it to have a certain format, for example:
(first 4 bytes) block type
(next 4 bytes) error code
(next 32 bytes) email address
(next 64 bytes) home address
(next 32 bytes) Full Name
and so forth. About 45 different fields that are padded with 0's to field size. I can use memcpy
and advance the pointer each time by the field size but it seems like a tedious task and an ugly code. Maybe a more clever and elegant way to create such a format?
Upvotes: 0
Views: 553
Reputation: 3776
To add to Nick's response, in C, but not C++, you can skip the union and directly zero the structure:
struct format_entry { char block_type[BLOCK_TYPE_SIZE]; char error_code[ERROR_CODE_SIZE]; char email_address[EMAIL_ADDRESS_SIZE]; char home_address[HOME_ADDRESS_SIZE]; char full_name[FULL_NAME_SIZE]; }; struct format_entry data; memset( &data, 0, sizeof data ); /* zero-fill structure */
If you need to update just some of the fields later on you might also consider making your own fill routine that assures zero fill.
char *strncpy0( char *target, const char *source, size_t s ) { memset( target, 0, s ); strncpy( target, source, s ); return target; }
While the above code is safer for early users of C, to be more efficient you could calculate the number of bytes at the end of target that strncpy() will not touch, then just fill those bytes.
Upvotes: 1
Reputation: 717
You can do such it using union
together with struct
:
#define BLOCK_TYPE_SIZE 4
#define ERROR_CODE_SIZE 4
#define EMAIL_ADDRESS_SIZE 32
#define HOME_ADDRESS_SIZE 64
#define FULL_NAME_SIZE 32
struct format_entry
{
char block_type[BLOCK_TYPE_SIZE];
char error_code[ERROR_CODE_SIZE];
char email_address[EMAIL_ADDRESS_SIZE];
char home_address[HOME_ADDRESS_SIZE];
char full_name[FULL_NAME_SIZE];
};
union format_union
{
char full_string[sizeof(struct format_entry)];
struct format_entry entry;
};
And then you can fill it in like these:
union format_union f;
memset (f.full_string, 0, sizeof f.full_string);
strcpy (f.entry.block_type, "TYPE");
strcpy (f.entry.error_code, "CODE");
strcpy (f.entry.email_address, "[email protected]");
strcpy (f.entry.home_address, "ADDR");
strcpy (f.entry.full_name, "NA ME");
Upvotes: 3
Reputation: 108986
strncpy()
, despite its name, is not a "string" function
char data[136/* maybe add 1 for extra '\0' */] = {0}; // fill array with zeroes
strncpy(data, "block type", 4);
strncpy(data + 4, "error code", 4);
strncpy(data + 8, "email address", 32);
strncpy(data + 40, "home address ...", 64);
strncpy(data + 104, "Full Name even if it is very very long", 32);
Upvotes: 1
Reputation: 20234
That's truly a tedious task. But it seems there is no better way.
Maybe you could conceal them into functions and never consider the ugly code inside.
Upvotes: 0