Reputation:
I have a function which reads in a character, one byte at a time, through the serial port. After these bytes are collected, they are passed to a method to process the bytes and message.
I know how to fix the problem (fix is below), but why do my bytes get truncated when I don't perform the fix?
unsigned char dpBuf[255];
...
// Pretend dpBuf has values 0x01 0x02 0x03 0x00 0x00 0x00 0x04 0x05
..
ProcessMsg(dpBuf);
..
void ProcessMsg(unsigned char *buff)
{
// buff comes in as 0x01 0x02 0x03 0x00 and rest is truncated
char p[255];
...
for (int i = 0; i < sizeof(buff); i++)
{
sprintf(p, " 0x%X ", (unsigned char)b[i]);
}
..
}
Fix:
ProcessMsg((unsigned char*)&dpBuf, length); // instead of sizeof() in the loop, use length
..
void ProcessMsg (unsigned char *buff, int length)
{
// buff comes in as the original character string and is not truncated
..
// do for loop, print out contents
}
Upvotes: 3
Views: 1778
Reputation: 101446
As everyone has said, in C++ a null-terminated char array is referred to as a string. The size of the buffer the chars are stored in can be larger then the "string length" in these terms. For example:
char inBuf [] = {0x01, 0x02, 0x03, 0x00, 0x00, 0x04, 0x05};
size_t bufSize = sizeof(inBuf);
size_t rawLen = strlen(inBuf);
...in this case the size of inBuf is 7, but strlen() returns 3.
Using ASCII you can't embed NULLs in a string. However, you can use the std::string if you want to embed NULLs. std::string is generally useful anyway, so check it out. Full working example:
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;
char inBuf [] = {0x01, 0x02, 0x03, 0x00, 0x00, 0x04, 0x05};
int main()
{
size_t bufSize = sizeof(inBuf);
size_t rawLen = strlen(inBuf);
string ss(inBuf, sizeof(inBuf));
size_t ssLen = ss.length();
cout << "Buffer Size = " << bufSize << ", Raw string length = " << rawLen << ", std::string length = " << ssLen;
return 0;
}
The program output is:
Buffer Size = 7, Raw string length = 3, std::string length = 7
Upvotes: 2
Reputation: 382
Sizeof(buff) returns the size of a const char * because that is the type of buff. I think the method you were looking for is strlen(buff), but even then strlen will stop when it finds a null terminator. http://www.cplusplus.com/reference/clibrary/cstring/strlen/
In standard ascii 0x00 is considered a null terminator which is generally considered the end of a c style string.
I might suggest you look at using stl strings as well http://www.cplusplus.com/reference/string/string/
Upvotes: 1
Reputation: 70204
Your code is wrong: for (int i = 0; i < sizeof(buff); i++)
It's using sizeof
which in fact equivalent to calling sizeof(unsigned char*)
. You have to pass the length explicitely.
Upvotes: 1
Reputation: 2871
buff is a pointer and hence its size is 4. sizeof(buff) = 4 sizeof(dpBuf) = 255
You wanted the second one.
Upvotes: 3
Reputation: 229563
buff
is declared as const char*
, so sizeof(buff)
returns the size of such a pointer, which seems to be 4 bytes on your machine. Therefore the first four bytes of the buffer are then printed in the loop.
It doesn't matter that dpBuf
is declared as an array of larger size because it is passed to the function as a pointer. To circumvent this problem you should add a parameter to the function where the size of the buffer is passed explicitly.
Upvotes: 11