2011-01-13 6 views
8

나는 네트워크 패킷의 길이에 기반하여 반복되는 for 루프를 만들려고 노력해왔다. API에는 event.packet-> dataLength에 의한 변수 (size_t)가 있습니다. 나는 0에서 event.packet-> dataLength - iterate를 반복하고 싶다. 반복 할 때마다 10 씩 증가 시키지만 문제가 생길 것이다.size_t를 정수로 변환 (C++)

해결책을 찾았지만 유용한 정보를 찾을 수 없었습니다. 나는 unsigned int로 size_t를 변환하려고 시도했지만 불행히도 그것은 작동하지 않았다. 기본적으로 내가 원하는 모든이있다 : 내 변환에서이 또는 시도 뭔가를 할

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

시간마다 비록 내가 < # 부분은 엄청난 숫자입니다. 그들은 실제 숫자를 출력하기 위해 "% u"를 사용하는 API에 대한 튜토리얼에서 printf 문을주었습니다.하지만 서명되지 않은 int로 변환 할 때 그것은 여전히 ​​올바르지 않습니다. 나는 여기서 어디로 가야할지 모르겠다. 어떤 도움을 크게 주시면 감사하겠습니다 :)

+3

생각해 봐 :'static_cast (- 1)'의 값은 무엇인가? 'event.packet-> dataLength'가 7보다 작 으면 어떻게 될까요? – genpfault

+0

왜'i'도'size_t'가 될 수 없습니까? 또한 길이가 항상 7 mod 10과 같지 않으면 시도하는 것이 매우 특이한 루프입니다. – OrangeDog

+0

'event.packet-> dataLength'를'int'로 형변환 해 보셨습니까? – Dawson

답변

4

i의 유형을 변경하지 않으시겠습니까?

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

함께 사용되는 모든 변수의 유형을 동일하게 유지하십시오. 캐스트는 피해야합니다.

size_t에 대한 형식 지정자가 C++ 03에 없으므로 가능한 가장 큰 부호없는 정수 유형으로 변환하여 인쇄해야합니다. (C++ 0x의 size_t의 형식 지정자는 %zu입니다. 그러나 어쨌든 printf를 사용해서는 안 : 스트림 더 자세한 될 수있다

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

동안, 그들은 더 많은 유형은 안전하고 무엇을 암기 할 필요가 없습니다.

실제 루프 논리에 결함이있을 수 있습니다. (dataLength - 7이 부정적 일 때 Genpfault 메모로 표시됩니다.)

+0

'dataLength - 7 '이 음수라면이 방법은 도움이되지 않을 것이고, 아무런 도움이되지 않을 것이라고 생각합니다. –

+0

@David : 아니, 그 이유는 내가 언급했다. 의도를 모른 채 수정 프로그램이 무엇인지 밝히기가 어렵습니다. – GManNickG

+0

나는 size_t를 이미 만들지 않으려 고 노력했다. – JeanOTF

1

dataLength> = 7입니까? dataLength-7의 결과가 음수이면 부호없는 것으로 해석하면 결과는 매우 큰 정수입니다.

0

i는 size_t를 사용하십시오.

printf의 경우 C99가 없으면 C90 만, 부호없는 long 또는 unsigned long long으로 캐스트됩니다. 예컨대 :

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

그렇지 않으면 먼저 event.packet->dataLength < 7 경우를 확인해야합니다 %의 즈

0

를 사용합니다. 이제 7보다 작 으면 0보다 작은 값이 부호없는 값으로 사용됩니다. 예 : 0 = 0x00000000; -1 = 0-1 = 0xFFFFFFFF.

다시 체크 :

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

서명 산술 모든 작업을 수행합니다. 보십시오 : 당신이 음수가 될 수있는 값과 부호없는 산술을 사용하고 < 같은 비교 연산자를 사용하여 시작하면, 당신은 문제에있어

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

. 사물을 쉽게 지킬 수 있습니다.

+0

흠, 나는 원래의 코멘트를 삭제해야했고, 표준 보증 된 행동에 관해서는 너무 많이 생각했습니다. non-perverse 컴파일러 (예 : * 실습 *)가있는 2의 보수 시스템에서 위의 코드가 작동합니다. 그러나 아마도 엄청난 부호없는 값을'int'로 변환하는 것은 공식적으로 UB입니다. 따라서 괄호를 수정하는 것이 가장 좋습니다. 건배, –

+0

@ Alf P. Steinbach : 고마워요. 귀하의 의견을 듣고 나서도 나는 당신이 의미하는 바를 깨닫는 순간을 가졌으므로 오타가 아니 었습니다. –

0

"내가 이와 같은 작업을하거나 내 전환을 시도 할 때마다 i < # 부분이 큰 숫자입니다."

이는 원래 패킷 길이가 7보다 작음을 나타냅니다 (7을 뺀 것).

하나의 해결 방법은 실제 크기가 충분한 부호있는 정수 유형을 사용하는 것이며 표준 라이브러리는 그 목적으로 ptrdiff_t을 제공합니다. 마찬가지로,

#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) 
    { 
     // ... 
    } 
} 

더 성가신 해결 방법은 크기가 적어도 7

건배 것을 확인하는 if에 모든 것을 포함하는 것입니다 & HTH., event.packet->dataLength 이후

0

은 부호를 반환 유형 size_t :

1) 인덱스 변수 유형으로 size_t을 사용하십시오.

2) 보장 된 수학은 언더 플로우가되지 않습니다. @beldaz. event.packet->dataLength에서 7을 뺀 것이 아니라 i에 7을 더합니다.

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