2011-01-13 24 views
8

Ho cercato di creare un ciclo for che si itera basandosi sulla lunghezza di un pacchetto di rete. Nell'API esiste una variabile (size_t) per event.packet-> dataLength. Voglio ripetere da 0 a event.packet-> dataLength - 7 aumentando i 10 ogni volta che itera ma sto avendo un mondo di problemi.Conversione di un size_t in un numero intero (C++)

Ho cercato soluzioni ma non sono riuscito a trovare nulla di utile. Ho provato a convertire il size_t in un unsigned int e facendo l'aritmetica con quello, ma sfortunatamente non ha funzionato. In pratica tutto quello che voglio è questo:

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

Anche se ogni volta che faccio qualcosa di simile a questo o tentativo di mie conversioni la # Parte I < è un numero enorme. Hanno dato una dichiarazione printf in un tutorial per l'API che utilizzava "% u" per stampare il numero reale, ma quando lo converto in un unsigned non è ancora corretto. Non sono sicuro di dove andare da qui. Qualsiasi aiuto sarebbe molto apprezzato :)

+3

Pensateci: qual è il valore di 'static_cast (- 1)'? Cosa succede quando 'event.packet-> dataLength' è minore di 7? – genpfault

+0

Perché non posso anche essere un 'size_t'? Inoltre, a meno che la lunghezza sia sempre uguale a 7 mod 10, questo è un loop molto particolare da provare. – OrangeDog

+0

Hai provato a lanciare 'event.packet-> dataLength' in un' int'? – Dawson

risposta

4

Perché non modificare il tipo di i?

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

Cercare di mantenere i tipi di tutte le variabili utilizzate insieme dello stesso tipo; calchi dovrebbero essere evitati.

Non esiste un identificatore di formato per size_t in C++ 03, è necessario eseguire il cast sul più grande numero intero senza segno che è possibile e stampare. (L'identificatore di formato per size_t in C++ 0x è %zu). Tuttavia, non si dovrebbe usare printf comunque:

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

Mentre i flussi possono essere più prolisso, sono più di tipo sicuro e non richiedono di memorizzare qualsiasi cosa.

Tenere presente che la logica del loop potrebbe essere errata. (Cosa succede, come note di genpfault, quando dataLength - 7 è negativo?)

+0

Questo non è d'aiuto se 'dataLength - 7' è negativo, e non penso che farà nulla di buono. –

+0

@David: No, non è così, è per questo che l'ho menzionato. Difficile dire quale sia la soluzione senza conoscere le intenzioni. – GManNickG

+0

Ho provato a fare in modo che size_t non abbia funzionato. – JeanOTF

1

Is dataLength> = 7? Se il risultato di dataLength-7 è negativo, se lo interpreti come unsigned, il risultato è un numero intero molto grande.

0

Utilizzare size_t per i.

Per printf, se non si dispone di C99, solo C90, eseguire il cast su unsigned long o unsigned long long. Es .:

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

utilizzare Altrimenti% zu

0

Si dovrebbe prima verificare se event.packet->dataLength < 7. Ora se è inferiore a 7 ottieni valori inferiori a 0 usati come non firmati: ad es. 0 = 0x00000000; -1 = 0 - 1 = 0xFFFFFFFF.

Anche in questo caso, il controllo:

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

fare tutto con l'aritmetica firmato. Prova:

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

Una volta di iniziare a utilizzare l'aritmetica senza segno con valori che possono essere negativi, e l'utilizzo di operatori di confronto come <, sei nei guai. Molto più facile mantenere le cose firmate.

+0

Hm, ho dovuto cancellare il mio commento originale, pensando completamente troppo in termini di comportamento garantito dallo standard. Sulla macchina a complemento a due, con un compilatore non perverso, cioè * in pratica *, funzionerà quanto sopra. Ma quella conversione di possibilmente un valore senza segno per 'int' è formalmente UB. Quindi, ripara meglio la parentesi. Saluti, –

+0

@Alf P. Steinbach: Grazie - anche dopo il tuo commento mi ci è voluto un momento per capire cosa intendevi, quindi non era solo un refuso. –

0

"ogni volta che faccio qualcosa di simile o provo le mie conversioni la parte i < # è un numero enorme."

Ciò indica che la lunghezza del pacchetto originale è inferiore a 7 (stai sottraendo 7).

Una correzione consiste nell'utilizzare un tipo intero con segno numerico sufficiente, in pratica, e la libreria standard fornisce ptrdiff_t a tale scopo. Come,

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

Una soluzione più ingombrante è quello di incorporare il tutto in un if che controlla che la dimensione sia almeno 7.

Acclamazioni & hth.,

0

Dal event.packet->dataLength restituisce un unsigned digitare size_t:

1) Utilizzare size_t come tipo di variabile di indice.

2) Assicurare che la matematica non trabocchi. @beldaz. Invece di sottrarre 7 da event.packet->dataLength, aggiungi 7 a i.

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