Reputation: 319
I'm currently using strlen
method to calculate the lenght of this string :
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
the main problem is that it always stops when encounter 00
, I think it's confusing it with the '\0'
! so I'm wondering if there's a replacement for this method or is there anything you can suggest to fix this issue .
P.S: I'm not sure if the question is duplicated I searched for the same problem but couldn't find a satisfying answer !
Edited :
my code :
unsigned char Response[269]={0x00};
unsigned char Response_PPSE[269];
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
the strlen calculate the length of this bytes only : 56 69 56 4F 74 65 63 68 32 00
Upvotes: 2
Views: 4353
Reputation: 1
In an application i made i created a custom "strlen" method using the following approach in order to correctly count the length even if i have null bytes in the middle of my data:
-We need to use except the char * containing the data, also the malloc'ed size.
-I pass the following parameters to the method: first parameter the char * str, second the size of malloc.
-Method works in the opposite way, from the MAX memory addr (memory addr of str + second parameter) to the first memory size, a while loop decrements the max memory address until first memory address reached but this while loop will break in case the first non NULL/0 char reached.
-Finally we return the difference of last MAX memory address and first memory address of char *, +1.
This is the my code:
size_t utils_strlen(const char * str, int max) {
const char * maxs;
maxs = str + max;
while(str<maxs) {
if(*maxs!=0) break;
maxs--;
}
return(maxs-str)+1;
}
Upvotes: 0
Reputation: 791
You mean the length of the array rather than the length of the response, so you want sizeof(Response) rather than strlen(Response) - presumably you know that the response is 269 bytes long because that's what the card protocol defines.
You also need Response_PPSE to be 2*269+1 bytes long, because otherwise your printf statements will run off the end of the array. And you need to set Response_PPSE[2*269]=0 to make it a valid null-terminated string.
Upvotes: 0
Reputation: 2305
The other answers I've seen so far are dancing around the real problem here. Which is that you need to understand what kind of string you're dealing with.
By historical convention, C represents strings as null terminated character arrays. That is the kind of string that strlen
expects. But your "string" contains null bytes. So it is not a null-terminated string, and strlen
will not do what you want.
More importantly, strlen
is extremely dangerous and should never be used in modern code. It's easy to cause security vulnerabilities with strlen, and the odds are good that if your program is using strlen
to examine responses received over the network, your program can be exploited to achieve denial or service or even remote code execution.
A safer alternative is strnlen
, if you give it the correct size limit. It's hard to be more precise about the right solution, because in your example the correct answer is just always 269, so there's really no variable-length string to measure.
Upvotes: 3
Reputation: 263627
unsigned char Response[269]={0x00};
This initializes Response
to a sequence of 269 identical values, each of which is zero. Note that 0x00
, 0
, and '\0'
are all the same thing.
strlen(Response)
This is actually invalid, though some compilers may permit it. strlen
requires an argument of type char*
; Response
is an array of unsigned char
, which is converted to a pointer of type unsigned char*
. The types are not compatible, and there is no implicit conversion. You should have gotten a compile-time warning (if you did, please include the warning in your question).
If we change the definition of Response
to:
char Response[269] = {0x00};
then the strlen
call becomes valid -- and will return 0
. strlen
scans for the first '\0'
null character -- and you've filled Response
with null characters.
At the top of your question, you say you have a string:
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
That doesn't have anything to do with the code you showed us. It's also ambiguous; is it a string of hex digits and spaces: "56 69 56 ..."
, or is it something like "\x56\x69\x56..."
? If the 56 69
sequence is intended to represent the contents of your array, please update your question to show the actual code that creates it.
Finally:
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
Calling strlen
on each iteration of the loop can be quite inefficient. strlen
has to scan the entire string each time to determine its length. Once you get the other problems straightened out, you should call strlen
once before the loop and use the stored value.
However, you probably don't want to be using strlen
in the first place. strlen
is applied to strings. A "string" is a sequence of characters terminated by a null character (0
, '\0'
, 0x00
). You appear to have a sequence of unsigned characters in which 0x00
is a valid value, not a terminator. Rather than using strlen
to compute the length of the array, you need to keep track of the length by some other means.
Upvotes: 3
Reputation: 62532
00
and '\0'
are the same thing.
It looks like you can an array of data are you're looking to get the length of the array rather than the length of a string. strlen
will scan an array up to the first null terminator. There's no equivalent for an arbitrary array, so you need to keep track of it yourself.
Upvotes: 3