सी

2012-09-02 10 views
10

में बाइट्स को इंट/यूंट में कनवर्ट करें मेरे पास एक हस्ताक्षरित चार सरणी है [248]; बाइट से भरा 2 एफ एएफ एफएफ 00 ईबी एबी सीडी ईएफ की तरह ..... यह ऐरे मेरा बाइट स्ट्रीम है जिसे मैं अपने डेटा को यूएआरटी (आरएस 232) से एक बफर के रूप में संग्रहीत करता हूं।सी

अब मैं बाइट्स को अपने uint16 और int32 के रूप में परिवर्तित करना चाहता हूं।

सी # में मैंने बिटकॉन्टर क्लास का ऐसा करने के लिए उपयोग किया। उदाहरण:

byte[] Array = { 0A, AB, CD, 25 }; 
int myint1 = BitConverter.ToInt32(bytes, 0); 
int myint2 = BitConverter.ToInt32(bytes, 4); 
int myint3 = BitConverter.ToInt32(bytes, 8); 
int myint4 = BitConverter.ToInt32(bytes, 12); 
//... 
enter code here 
Console.WriteLine("int: {0}", myint1); //output Data... 

क्या सी में एक समान कार्य है? (कोई .net, मैं Keil संकलक का प्रयोग कर एक माइक्रोकंट्रोलर पर क्योंकि कोड चल रहा है)

सादर सैम

समाधान: रास्ता ए)

पहले मैं बदल सकते हैं या के रूप में सरणी प्रारंभ करने के लिए किया था एक uint8_t ARRAY [248];

uint32_t* myint1 = (uint32_t *)&RXBUFF[2]; //test 
uint16_t* myint2 = (uint16_t *)&RXBUFF[6]; //test3 

ध्यान दें:: पूर्णांक मूल्य "1985" हेक्स में myint2 में 0x07C1 के रूप में प्रस्तुत किया जाता है तो मैं आपकी मदद के साथ इस कोड का इस्तेमाल किया। बाइट जिसे मैंने भेजा था "सी 1 07" था इसलिए माइक्रोकंट्रोलर बाइट ऑर्डर

बदल रहा है, मैं अन्य तरीकों का भी परीक्षण करूंगा।

WR सैम :)

उत्तर

8

हां वहाँ है। अपने बाइट्स मान लें कर रहे हैं में:

uint8_t bytes[N] = { /* whatever */ }; 

हम जानते हैं कि एक 16 बिट पूर्णांक सिर्फ दो 8 बिट पूर्णांकों concatenated है कि, है, अर्थातएक 256 की एक बहु है या वैकल्पिक रूप से 8 से स्थानांतरित कर दिया है:

uint16_t sixteen[N/2]; 

for (i = 0; i < N; i += 2) 
    sixteen[i/2] = bytes[i] | (uint16_t)bytes[i+1] << 8; 
      // assuming you have read your bytes little-endian 
इसी तरह 32 बिट के लिए

:

uint32_t thirty_two[N/4]; 

for (i = 0; i < N; i += 4) 
    thirty_two[i/4] = bytes[i] | (uint32_t)bytes[i+1] << 8 
     | ((uint32_t)bytes[i+2] << 16 | (uint32_t)bytes[i+3] << 24; 
      // same assumption 

तो बाइट्स बड़े endian पढ़ रहे हैं, निश्चित रूप से आप क्रम को उलट :

bytes[i+1] | (uint16_t)bytes[i] << 8 

और

bytes[i+3] | (uint32_t)bytes[i+2] << 8 
    | (uint32_t)bytes[i+1] << 16 | (uint32_t)bytes[i] << 24 

नोट संग्रहीत पूर्णांक में endian सत्ता और वास्तुकला चलने के endian सत्ता के बीच एक अंतर है कि। इस उत्तर में निर्दिष्ट एंडियन-नेस संग्रहीत पूर्णांक का है, यानी bytes की सामग्री। समाधान endian-ness is taken care of when shifting के बाद चल रहे आर्किटेक्चर के एंडियन-नेस से स्वतंत्र हैं।

+0

क्या होगा यदि इसका बड़ा एंडियन? – Sam

+0

तो आप सबसे महत्वपूर्ण बिट्स के बजाय कम से कम महत्वपूर्ण बिट्स में स्थानांतरित करते हैं। – devsnd

+0

@twall, मुझे लगता है कि आप बाइट्स का मतलब है। –

15

वहाँ सी में आप के लिए यह करने के लिए आप बाइट्स अपने 16- और 32-बिट खुद पूर्णांकों में वापस इकट्ठा करने के लिए होगा कोई मानक सुविधा नहीं होती। अंतहीनता के बारे में सावधान रहें!

यहाँ एक सरल थोड़ा-endian उदाहरण है:

extern uint8_t *bytes; 
uint32_t myInt1 = bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24); 

एक बड़े endian प्रणाली के लिए, यह सिर्फ विपरीत क्रम है:

uint32_t myInt1 = (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3]; 

आप के साथ भाग प्राप्त करने में सक्षम हो सकता है:

uint32_t myInt1 = *(uint32_t *)bytes; 

यदि आप संरेखण के मुद्दों के बारे में सावधान हैं।

+1

मैं इसे स्थानांतरित करने से पहले प्रत्येक 'बाइट []' 'uint32_t' पर डाल दूंगा। जैसा ऊपर लिखा गया है, उन्हें बदलाव करने से पहले 'int' पर डाला जाएगा, लेकिन 'int' को 32 बिट्स की आवश्यकता नहीं है। –

+0

यह सबसे सुरक्षित, सहमत होगा। –

+0

मान लीजिए 'बाइट्स' देशी एंडियन है, आप किस तरह के संरेखण के मुद्दों में भाग लेंगे? या, मुझे लगता है, किस तरह की परिस्थितियों में संरेखण एक समस्या है? – Azmisov

6

आप सीधे अपने सरणी से एक uint16_t * सूचक बना सकते हैं।

uint8_t bytes[N] = { /* whatever */ }; //Shamelessly stolen from Shanbaz 

uint16_t* viewAsUint16_t = (uint16_t *)&bytes[0]; 

अब आप तत्वों तक पहुंचने के लिए अपने पॉइंटर का उपयोग कर सकते हैं।

ध्यान दें कि यह endiness मानती है कि आपके मशीन के लिए सही है। आप इन uint16_t रों अधिक पाश की जरूरत है और ntohs की तरह एक कार्यों का उपयोग (सबसे ऑपरेटिंग सिस्टम पर avaialable होना चाहिए) endiness के लिए सही करने के लिए हो सकता है।

+0

मैं इसे आजमाउंगा। – Sam

+0

मैंने आपके कोड की कोशिश की लेकिन ऐसा लगता है कि यह काम नहीं करता है। मैंने आउटपुट को डिबगर और कंसोल से एक तस्वीर के रूप में सहेजा: [link] (http://s18.postimage.org/fipv7svp3/debugbyte.png) – Sam

0
  char letter = 'A'; 
      size_t filter = letter; 
      filter = (filter << 8 | filter); 
      filter = (filter << 16 | filter); 
      filter = (filter << 32 | filter); 
      printf("filter: %#I64x \n", filter); 

परिणाम: "फिल्टर: 0x4141414141414141"

0

थोड़ा-endian के मामले में, तुम सिर्फ memcpy का उपयोग नहीं कर सकते हैं?

memcpy((char*)&myint1, aesData.inputData[startindex], length);