2011-01-13 13 views
8

Próbowałem utworzyć pętlę for, która będzie iterować w oparciu o długość pakietu sieciowego. W interfejsie API istnieje zmienna (size_t) według właściwości event.packet-> dataLength. Chcę iterować od 0 do event.packet-> dataLength - 7 zwiększanie i o 10 przy każdym iteracji, ale mam świat kłopotów.Konwertowanie size_t na liczbę całkowitą (C++)

Szukałem rozwiązań, ale nie mogłem znaleźć niczego przydatnego. Próbowałem przekonwertować size_t na unsigned int i zrobić arytmetykę z tym, ale niestety to nie zadziałało. W zasadzie wszystko czego chcę to:

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

Choć za każdym razem zrobić coś takiego lub próbę moich konwersji I < # jest to ogromna liczba. Wydali instrukcję printf w samouczku dla interfejsu API, który użył "% u" do wydrukowania rzeczywistej liczby, jednak kiedy przekonwertowałem ją na niepodpisaną int, nadal jest ona niepoprawna. Nie jestem pewien, dokąd się udać. Każda pomoc będzie bardzo mile widziane :)

+3

Pomyśl o tym: Jaka jest wartość 'static_cast (- 1)'? Co się dzieje, gdy 'event.packet-> dataLength' jest mniejsze niż 7? – genpfault

+0

Dlaczego 'i' nie może być także' size_t'? Ponadto, chyba że długość jest zawsze równa 7 mod 10, jest to bardzo osobliwa pętla, którą należy wykonać. – OrangeDog

+0

Czy próbowałeś rzucić 'event.packet-> dataLength' na' int'? – Dawson

Odpowiedz

4

Dlaczego nie zmienić typu i?

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

Staraj się zachować typy wszystkich zmiennych używanych razem tego samego typu; należy unikać odlewania.

Nie ma specyfikatora formatu dla size_t w C++ 03, musisz odrzucić do największego bez znaku typu całkowitego, jaki możesz i wydrukować. (Specyfikator formatu dla size_t w C++ 0x to %zu). Jednak nie należy używać printf w każdym razie:

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

Podczas strumienie mogą być bardziej gadatliwy, są one bardziej rodzaj bezpieczne i nie wymaga niczego zapamiętać.

Należy pamiętać, że rzeczywista logika pętli może być wadliwa. (Co się stanie, jak zauważa genpfault, gdy dataLength - 7 ma wartość ujemną?)

+0

To nie pomoże, jeśli 'dataLength - 7' jest ujemna, i nie sądzę, że to przyniesie coś dobrego. –

+0

@ David: Nie, nie, dlatego to wspomniałem. Trudno powiedzieć, co to jest poprawka, nie znając intencji. – GManNickG

+0

Próbowałem, aby i size_t już nie działało. – JeanOTF

1

Czy dataLength> = 7? Jeśli wynik dataLength-7 jest ujemny, jeśli interpretujesz go jako unsigned, wynikiem jest bardzo duża liczba całkowita.

0

Użyj size_t dla i.

Dla printf, jeśli nie masz C99, tylko C90, rzutowanie na niepodpisane długie lub niepodpisane długie. Np .:

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

Inaczej użyć% zu

0

Najpierw należy sprawdzić, czy event.packet->dataLength < 7. Teraz, gdy jest mniej niż 7, otrzymujesz wartości mniejsze niż 0, używane jako niepodpisane: np. 0 = 0x00000000; -1 = 0 - 1 = 0xFFFFFFFF.

Znów czek:

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

Czy wszystko z podpisanym arytmetyki. Spróbuj:

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

Po rozpoczęciu korzystania z arytmetyki bez znaku wartości, które mogą być ujemne, a przy użyciu operatorów porównania jak <, jesteś w tarapatach. O wiele łatwiejsze jest utrzymanie podpisu.

+0

Hm, musiałem usunąć mój pierwotny komentarz, myśląc całkowicie za dużo pod względem gwarantowanego standardu zachowania. Na maszynie uzupełniającej dwójki z nie przewrotnym kompilatorem, tj. * W praktyce *, powyższe działa. Ale ta konwersja potencjalnie ogromnej, niepodpisanej wartości na "int" jest formalnie UB. Najlepiej naprawić nawias. Pozdrawiam, –

+0

@Alf P. Steinbach: Dzięki - nawet po Twoim komentarzu zajęło mi chwilę, aby zrozumieć, co masz na myśli, więc to nie był tylko literówka. –

0

"Za każdym razem, gdy robię coś takiego lub próbuję dokonać konwersji, część" i < # jest ogromną liczbą ".

Wskazuje, że oryginalna długość pakietu jest mniejsza niż 7 (odejmujesz 7).

Jedną z poprawek jest użycie w praktyce wystarczająco dużej liczby ze znakiem, a standardowa biblioteka zapewnia w tym celu ptrdiff_t. Podobnie jak

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

Bardziej kłopotliwe jest obejście osadzić całą rzecz w if który sprawdza, że ​​wielkość jest co najmniej 7.

Cheers & HTH.,

0

Od event.packet->dataLength zwraca niepodpisany wpisz size_t:

1) Użyj size_t jako typu zmiennej indeksowej.

2) Ubezpiecz matematyki nie jest niedopełnione. @beldaz. Zamiast odejmować 7 z event.packet->dataLength, dodaj 7 do i.

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