我有一個n字節的緩衝區,但我只想從字節3中讀取sizeof(某些)字節,這意味着我不想從緩衝區讀取字節1和2。例如...有沒有「lseek」移動?
對於某些緩衝區,字節1 ='a',字節2 ='b',字節3 = uint64_t變量。我想要做的是一樣的東西
1. set begin to byte 3
2. read in sizeof(uint64_t) bytes from buffer using memmove
我有一個n字節的緩衝區,但我只想從字節3中讀取sizeof(某些)字節,這意味着我不想從緩衝區讀取字節1和2。例如...有沒有「lseek」移動?
對於某些緩衝區,字節1 ='a',字節2 ='b',字節3 = uint64_t變量。我想要做的是一樣的東西
1. set begin to byte 3
2. read in sizeof(uint64_t) bytes from buffer using memmove
首先,有點澄清。 C數組索引從0開始,而不是從1開始,因此更準確地說,字節0是'a'
,字節1是'b'
。其次,您的第三個字節不能包含變量uint64_t
,但索引2很可能是uint64_t
對象的開始的。
不,不存在lseek
相當於memmove()
- 因爲不同於文件操作,memmove()
的調用必須指定起始點。
而在這種情況下,您不妨使用memcpy()
而不是memmove()
。它們之間的唯一區別是memmove()
正確處理重疊的緩衝區。由於你的源和目標是不同的對象,這不是一個問題。它不會嚴重影響你的代碼的速度,但是任何閱讀它的人都不會想知道你爲什麼選擇使用memmove()
。
考慮:
unsigned char buf[SOME_SIZE];
uint64_t target;
你可以做這樣的事情:
memcpy(&target, buf+2, sizeof target);
請注意,我用sizeof target
而非sizeof (uint64_t)
。兩者都可以工作,但使用sizeof target
可以使您的代碼更具彈性(稍後在更改時不易受到錯誤的影響)。如果您決定更改target
的類型,則不需要記住更改memcpy()
調用中的類型。
爲什麼不直接使用此:
uint64_t num;
num = * ((uint64_t *) (buffer + 2))
因爲如果該地址未對齊,它可能會失敗。 – 2012-03-09 00:02:37
沒錯。好的,你最好使用某種memcpy,但是我看到你已經提出了一個很好的答案來解釋:) – xato 2012-03-09 00:07:48
指針數學和鑄造對你來說太難了嗎? – 2012-03-08 23:59:24