2011-01-13 46 views
8

Tôi đã cố gắng tạo vòng lặp for lặp lại dựa trên độ dài của gói mạng. Trong API có tồn tại một biến (size_t) bởi event.packet-> dataLength. Tôi muốn lặp lại từ 0 đến event.packet-> dataLength - 7 tăng i 10 mỗi lần nó lặp lại nhưng tôi đang có một thế giới rắc rối.Chuyển đổi size_t thành số nguyên (C++)

Tôi đã tìm giải pháp nhưng không thể tìm thấy bất kỳ điều gì hữu ích. Tôi đã cố gắng chuyển đổi size_t đến một int unsigned và làm số học với điều đó nhưng tiếc là nó không hoạt động. Về cơ bản tất cả những gì tôi muốn là:

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

Mặc dù mỗi lần tôi làm điều này hoặc cố gắng chuyển đổi, tôi < # part là một số lượng lớn. Họ đã đưa ra một tuyên bố printf trong một hướng dẫn cho API mà sử dụng "% u" để in số thực tế tuy nhiên khi tôi chuyển đổi nó thành một unsigned int nó vẫn không chính xác. Tôi không chắc phải đi đâu từ đây. Bất kỳ trợ giúp nào cũng sẽ được đánh giá cao :)

+3

Hãy suy nghĩ về nó: Giá trị của 'static_cast (- 1)' là gì? Điều gì sẽ xảy ra khi 'event.packet-> dataLength' nhỏ hơn 7? – genpfault

+0

Tại sao không thể 'tôi' là' size_t'? Ngoài ra, trừ khi chiều dài luôn luôn bằng 7 mod 10, đây là một vòng lặp rất đặc biệt để cố gắng. – OrangeDog

+0

Bạn có cố gắng truyền 'event.packet-> dataLength' sang' int' không? – Dawson

Trả lời

4

Tại sao bạn không thay đổi loại i?

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

Cố gắng giữ các loại của tất cả các biến được sử dụng cùng loại; phôi nên tránh.

Không có trình định dạng định dạng cho size_t trong C++ 03, bạn phải truyền tới loại số nguyên không dấu lớn nhất mà bạn có thể và in. (Định dạng thông số cho size_t trong C++ 0x là %zu). Tuy nhiên, bạn không nên sử dụng printf anyway:

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

Trong khi con suối có thể tiết hơn, họ đang loại hơn an toàn và không yêu cầu bạn phải ghi nhớ bất cứ điều gì.

Hãy nhớ rằng logic vòng lặp thực tế của bạn có thể thiếu sót. (Điều gì xảy ra, như ghi chú genpfault, khi dataLength - 7 là âm?)

+0

Điều này sẽ không giúp ích nếu 'dataLength - 7' là âm, và tôi không nghĩ nó sẽ làm tốt. –

+0

@ David: Không, không phải vậy, đó là lý do tôi đề cập đến nó. Khó để nói những gì sửa chữa là không biết ý định. – GManNickG

+0

Tôi đã thử làm cho i size_t đã không hoạt động. – JeanOTF

1

Dữ liệu có phải là bước sóng> = 7? Nếu kết quả của dataLength-7 là âm, nếu bạn giải thích nó là unsigned, kết quả là một số nguyên rất lớn.

0

Sử dụng size_t cho i.

Đối với printf, nếu bạn không có C99, chỉ C90, truyền tới chưa ký dài hoặc không ký. Ví dụ .:

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

Nếu không sử dụng% zu

0

Trước tiên, bạn nên kiểm tra nếu event.packet->dataLength < 7. Bây giờ nếu ít hơn 7 thì bạn nhận được các giá trị nhỏ hơn 0 được sử dụng như chưa ký: ví dụ: 0 = 0x00000000; -1 = 0 - 1 = 0xFFFFFFFF.

Một lần nữa, việc kiểm tra:

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

làm tất cả mọi thứ với số học ký kết. Hãy thử:

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

Khi bạn bắt đầu sử dụng số học chưa ký với giá trị có thể âm và sử dụng toán tử so sánh như <, bạn đang gặp sự cố. Dễ dàng hơn nhiều để giữ mọi thứ được ký kết.

+0

Hm, tôi phải xóa nhận xét ban đầu của mình, suy nghĩ quá nhiều về hành vi được đảm bảo tiêu chuẩn. Trên máy bổ sung của hai, với trình biên dịch không hoàn toàn, tức là * trong thực tế *, ở trên sẽ hoạt động. Nhưng sự chuyển đổi của giá trị unsigned lớn có thể thành 'int' chính thức là UB. Vì vậy, sửa chữa tốt nhất dấu ngoặc đơn. Chúc mừng, –

+0

@Alf P. Steinbach: Cảm ơn - ngay cả sau khi nhận xét của bạn, tôi đã mất một chút thời gian để nhận ra ý của bạn, vì vậy nó không chỉ là lỗi đánh máy. –

0

"mỗi lần tôi làm điều gì đó như thế này hoặc cố gắng chuyển đổi của tôi, phần i < # là một số lượng lớn".

Điều đó cho biết rằng độ dài gói ban đầu nhỏ hơn 7 (bạn sẽ trừ 7).

Một khắc phục là sử dụng loại số nguyên đã ký đủ lớn trong thực tế và thư viện chuẩn cung cấp ptrdiff_t cho mục đích đó. Giống như,

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

Một workaround cồng kềnh hơn là để nhúng toàn bộ điều trong một if để kiểm tra rằng kích thước tối thiểu là 7.

Cheers & h.,

0

Kể từ event.packet->dataLength trả về một unsigned loại size_t:

1) Sử dụng size_t làm loại biến chỉ mục.

2) Toán học đảm bảo không bị tràn. @beldaz. Thay vì trừ 7 từ event.packet->dataLength, hãy thêm 7 đến i.

// for (int i = 0; i < event.packet->dataLength - 7; i+=10) { } 
for (size_t i = 0; i + 7 < event.packet->dataLength; i += 10) { } 
Các vấn đề liên quan