confused about copying strings


A

Angus

The sample code below simulates receiving a protocol message with a tlv
structure - type/length/data_value.

I am confused about copying the actual data to a temp string. I use *data++
= *mybytes; - but after the copy tyhe pointer points to the end of the
string - so I have to return back to the beginning of the string to be able
to eg print it out. In this sort of situation what coding pattern should I
be using to efficiently copy my data?

In a real situation there would probqably be another message after this
one - another tlv.



int main()
{
unsigned char buffer[] = {3,9,"123456789"};
//unsigned char buffer[] = {0,1,'A'};
unsigned char* mybytes = buffer;
bool done(false);

int type = *mybytes++; //dereferences ptr and returns value - then
increments ptr
int size = *mybytes++;
switch(type)
{
case 0:
{
char c = *mybytes++;
printf("char data type: %c, size: %i\n", c, size);
break;
}
case 3: //string type
{
char* data = (char*)malloc(size);
do
{
*data++ = *mybytes; // copies data
} while(*mybytes++);

for(int j = 0; j <= size; ++j)
*data--;

printf("char data type: %s, size: %i\n", data, size);
free(data);
break;
}
}

return 0;
}
 
Ad

Advertisements

I

Ian Collins

The sample code below simulates receiving a protocol message with a tlv
structure - type/length/data_value.

I am confused about copying the actual data to a temp string. I use *data++
= *mybytes; - but after the copy tyhe pointer points to the end of the
string - so I have to return back to the beginning of the string to be able
to eg print it out. In this sort of situation what coding pattern should I
be using to efficiently copy my data?

In a real situation there would probqably be another message after this
one - another tlv.



int main()
{
unsigned char buffer[] = {3,9,"123456789"};
//unsigned char buffer[] = {0,1,'A'};
unsigned char* mybytes = buffer;
bool done(false);

You must have compiled with a C++ compiler! bool done = false;
int type = *mybytes++; //dereferences ptr and returns value - then
increments ptr
int size = *mybytes++;
switch(type)
{
case 0:
{
char c = *mybytes++;
printf("char data type: %c, size: %i\n", c, size);
break;
}
case 3: //string type
{
char* data = (char*)malloc(size);

You don't need the cast.
do
{
*data++ = *mybytes; // copies data
} while(*mybytes++);

for(int j = 0; j<= size; ++j)
*data--;

Rather than rewind like this, you could have preserved the value of data
before the loop, or just written data -= size here. Better still
replace the loops with:

memcpy( data, mybytes, size );

Not forgetting to include <string.h>.
 
I

Ian Collins

Since you know in advance that you have sufficient storage to store the
copy, use strcpy.

int dtype = *mybytes++;
int dsize = *mybytes++;
size_t size = dsize;
char *data = malloc(size);
if(data != NULL)
{
if(strlen(mybytes) < size)

That would would work in the special case here of a string literal, but
probably wouldn't be much use with data over the wire, unless it was
null terminated.

<meta>
It's odd that Thunderbird has munted your formatting, but no the OPs
</meta>
 
I

Ian Collins

I checked the OP's code, and his end test is for null termination. I
assumed, therefore, that he has null-terminated data.

So I see, I'd missed that. It was probably a bug in the OPs's code!
Thunderbird is indeed odd. But KNode is all the way upstairs, and it's
/such/ a long way. And someone's nicked my chair from that desk.

:)
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top