开发者

Converting a size_t into an integer (c++)

I've been trying to make a for loop that will iterate based off of the length of a network packet. In the API there exists a variable (size_t) by event.packet->dataLength. I want to iterate from 0 to event.packet->dataLength - 7 increasing i by 10 each time it iterates but I am having a world of trouble.

I looked for solutions but have been unable to find anything useful. I tried converting the size_t to an unsigned int and doing the arithmetic with that but unfortunately it didn't work. Basically all I want is this:

for (int i = 0; i < event.packet->dataLength - 7; i+=10) { }

Though every time I do something l开发者_JAVA百科ike this or attempt at my conversions the i < # part is a huge number. They gave a printf statement in a tutorial for the API which used "%u" to print the actual number however when I convert it to an unsigned int it is still incorrect. I'm not sure where to go from here. Any help would be greatly appreciated :)


Why don't you change the type of i?

for (size_t i = 0; i < event.packet->dataLength - 7; i+=10) { }

Try to keep the types of all variables used together the same type; casts should be avoided.

There is no format specifier for size_t in C++03, you have to cast to the largest unsigned integer type you can and print that. (The format specifier for size_t in C++0x is %zu). However, you shouldn't be using printf anyway:

std::cout << i; // print i, even if it's a size_t

While streams may be more verbose, they're more type safe and don't require you to memorize anything.

Keep in mind your actual loop logic may be flawed. (What happens, as genpfault notes, when dataLength - 7 is negative?)


Do everything with signed arithmetic. Try:

for (int i = 0; i < int(event.packet->dataLength) - 7; i+=10) { }

Once you start using unsigned arithmetic with values that may be negative, and using comparison operators like <, you're in trouble. Much easier to keep things signed.


Is dataLength >= 7? If the result of dataLength-7 is negative, if you interpret it as unsigned, the result is a very large integer.


Use size_t for i.

For printf, if you don't have C99, only C90, cast to unsigned long, or unsigned long long. E.g.:

for (size_t i = 0; i < 10; ++i)
        //printf("%llu\n", (unsigned long long)i);
        printf("%lu\n", (unsigned long)i);

Otherwise use %zu


You should first check if event.packet->dataLength < 7. Now if it's less then 7 you get values less than 0 used as unsigned: e.g. 0 = 0x00000000; -1 = 0 - 1 = 0xFFFFFFFF.

Again, the check:

if (event.packet->dataLength < 7) {
  ...
} else {
  for (size_t i = 0; i < event.packet->dataLength - 7; i+=10) { }
}


"every time I do something like this or attempt at my conversions the i < # part is a huge number."

That indicates that original packet length is less than 7 (you're subtracting 7).

One fix is to use an in-practice-large-enough signed integer type, and the standard library provides ptrdiff_t for that purpose. Like,

#include <stdlib.h>   // Not sure, but I think it was this one.

typedef ptrdiff_t    Size;
typedef Size         Index;

void foo()
{
    // ...
    for( Index i = 0; i < Size( event.packet->dataLength ) - 7; i += 10 )
    {
        // ...
    }
}

A more cumbersome workaround is to embed the whole thing in an if that checks that the size is at least 7.

Cheers & hth.,


Since event.packet->dataLength returns an unsigned type size_t:

1) Use size_t as the index variable type.

2) Insure math does not underflow. @beldaz. Rather than subtract 7 from event.packet->dataLength, add 7 to i.

// for (int i = 0; i < event.packet->dataLength - 7; i+=10) { }
for (size_t i = 0; i + 7 < event.packet->dataLength; i += 10) { }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜