Click to See Complete Forum and Search --> : strcat throwing an exception


leojose
November 20th, 2005, 09:51 AM
I am trying to construct a character string using different data types.
This is what I have done...
char sBeaconMsg[50];
strcpy(sBeaconMsg,"Test");

BYTE vID = (BYTE)0x10;
UCHAR typeID = (UCHAR)1;
USHORT res = (USHORT)0;
BYTE statCode = (BYTE)0x00;
UCHAR headers = (UCHAR)0;

strcat(sBeaconMsg,(char*)&vID);
strcat(sBeaconMsg,(char*)&typeID);
strcat(sBeaconMsg,(char*)&res);
strcat(sBeaconMsg,(char*)&statCode);
strcat(sBeaconMsg,(char*)&headers);
Although it builds correctly, at run-time the strcat throws an unhandled exception. Why does that happen?
Is there any other method of accomplishing my goal?

NoHero
November 20th, 2005, 09:58 AM
strcat() can only append a null terminated character arrays together. And not a int or a long. The content of your BYTE's and WORD's are interpreted as null terminated c strings - but they are none - so the strcat method keeps going on in the heap until he finds a null terminator. This leads to the access violation exception.

You can use sprintf() instead to format your string:

char sBeaconMsg[50]={0};

BYTE vID = (BYTE)0x10;
UCHAR typeID = (UCHAR)1;
USHORT res = (USHORT)0;
BYTE statCode = (BYTE)0x00;
UCHAR headers = (UCHAR)0;

sprintf(sBeaconMsg, "Test%d %d %d %d %d", vID, typeID, res, statCode, headers);

leojose
November 20th, 2005, 10:20 AM
Thanks for the suggestion...

But what happens when I use sprintf is that the value vID = 10h or 16d, which is actually a 1 byte character (non-printable char SOH) gets converted to a 2 byte character of 1 and 6. Same is the case for the remaining data types.
This is how many bytes each one contains.

BYTE vID = (BYTE)0x10; // 1byte
UCHAR typeID = (UCHAR)1; // 1byte
USHORT res = (USHORT)0; // 2byte
BYTE statCode = (BYTE)0x00; //1byte
UCHAR headers = (UCHAR)0; //1byte

olivthill
November 20th, 2005, 02:21 PM
You might try to simply put your data at the end of your string like this:char sBeaconMsg[50];
strcpy(sBeaconMsg,"Test");

BYTE vID = (BYTE)0x10;
UCHAR typeID = (UCHAR)1;
USHORT res = (USHORT)0;
BYTE statCode = (BYTE)0x00;
UCHAR headers = (UCHAR)0;

sBeaconMsg[strlen("Test")] = (char)vID;
sBeaconMsg[strlen("Test")+1] = (char)typeID;
sBeaconMsg[strlen("Test")+2] = (char)(res >> 8) & 0xFF);
sBeaconMsg[strlen("Test")+3] = (char)(res & 0xFF);
sBeaconMsg[strlen("Test")+4] = (char)statCode;
sBeaconMsg[strlen("Test")+5] = (char)headers;

leojose
November 21st, 2005, 12:17 AM
Thanks olivthill...a pretty innovative way of doing it;)

leojose
November 21st, 2005, 04:22 AM
All said and done...now I'm facing a new challenge.

The data from Client to Server is somethign like
Test**000*0
where * is a non-printable character
and 0 is a Null character (single byte value 0)

The data Server receives from Client is
Test**0
The server thinks the 0 means a string termination, and so what value I am able to read using the recv command does not contain anything beyond it.
The Client cannot send each byte separately, it will come as a string as shown above.
How do I then tell my application (server) to read the entire string? I am aware of the length of the string that will come...will that be of any help?

leojose
November 21st, 2005, 04:57 AM
ok...i was able to resolve this on my own. But instead of deleting this post I decide to answer it myself as it might help somebody else.At the same time it is open to comments if I am wrong.
The server thinks the 0 means a string termination, and so what value I am able to read using the recv command does not contain anything beyond it.

No. the server reads the entire string equivalent to the size of the buffer we are using. Because i was able to extract all the data using a for loop

ret = recvfrom(sUDPLocal, szBuff, DEFAULT_BUFFER, 0, (struct sockaddr *)&from,&fromlen)
.
.
.
for(int i=0; i<20; i++)
{
cout << "Byte " << i << " = " << szBuff[i] << endl;
}
So if i wan't to read just 20 bytes, i will set the for loop accordingly.

How do I then tell my application (server) to read the entire string? I am aware of the length of the string that will come...will that be of any help?
Use the for loop as indicated above

Q:does that mean the bigger the buffer of szBuff, more the data it will store regardless of how big the incoming string is?

leojose
November 21st, 2005, 08:21 AM
Another find
I was using the send command this way...
ret = send(sockTcpTarget,szTcpMessage,strlen(szTcpMessage)+1,0);
strlen will extract the length upto the next null character, and so the length being passed by the client itself was wrong. I changed that to 16 (the actual number of bytes I was transmitting) and the I was able to read the values beyond the null terminator.