2012-04-25 45 views
14

मेरे पास एक हस्ताक्षरित int संख्या (2 बाइट) है और मैं इसे बिना हस्ताक्षरित चार प्रकार में परिवर्तित करना चाहता हूं। मेरी खोज से, मुझे लगता है कि ज्यादातर लोग निम्न कार्य करने की सलाह देते हैं:सी - हस्ताक्षरित int सरणी रूपांतरण के लिए हस्ताक्षरित int

unsigned int x; 
... 
unsigned char ch = (unsigned char)x; 

सही दृष्टिकोण है? मैं पूछता हूं क्योंकि हस्ताक्षरित चार 1 बाइट है और हमने 2 बाइट डेटा से 1 बाइट तक कास्ट किया है।

किसी डेटा हानि को रोकने के लिए, मैं बिना हस्ताक्षरित char [] की एक सरणी बनाना चाहता हूं और व्यक्तिगत बाइट को सरणी में सहेजना चाहता हूं। मैं निम्नलिखित पर अटक कर रहा हूँ:

unsigned char ch[2]; 
unsigned int num = 272; 

for(i=0; i<2; i++){ 
     // how should the individual bytes from num be saved in ch[0] and ch[1] ?? 
} 

इसके अलावा, कैसे हम [2] अहस्ताक्षरित int वापस करने के लिए अहस्ताक्षरित चार में बदल सकते हैं।

बहुत बहुत धन्यवाद।

+0

के संभावित डुप्लिकेट [लघु हस्ताक्षर किए में C++ बाइट के लिए] (http://stackoverflow.com/questi ऑन/1028810 9/हस्ताक्षरित-शॉर्ट-टू-बाइट-इन-सी) –

उत्तर

16

आप उस मामले में memcpy उपयोग कर सकते हैं:

memcpy(ch, (char*)&num, 2); /* although sizeof(int) would be better */ 

इसके अलावा, कैसे होगा [2] अहस्ताक्षरित पूर्णांक के लिए वापस अहस्ताक्षरित चार परिवर्तित।

वैसे ही, बस memcpy के तर्कों को उलट दें।

15

कैसे के बारे में:

ch[0] = num & 0xFF; 
ch[1] = (num >> 8) & 0xFF; 

बातचीत आपरेशन एक व्यायाम के रूप में छोड़ दिया जाता है।

7

संघ का उपयोग करने के बारे में कैसे?

union { 
    unsigned int num; 
    unsigned char ch[2]; 
} theValue; 

theValue.num = 272; 
printf("The two bytes: %d and %d\n", theValue.ch[0], theValue.ch[1]); 
4

बेशक, बड़े मूल्य वाले बड़े अक्षरों के सरणी को इस मान के रूप में बिल्कुल बड़ा होना चाहिए। तो आप बस का नाटक कर सकते हैं कि यह बड़ा मूल्य पहले से ही वर्ण की एक सरणी है:

unsigned int x = 12345678;//well, it should be just 1234. 
unsigned char* pChars; 

pChars = (unsigned char*) &x; 

pChars[0];//one byte is here 
pChars[1];//another byte here 

(एक बार जब आप समझ में क्या हो रहा है, यह किसी भी चर बिना किया जा सकता, सब सिर्फ कास्टिंग)

+2

यदि '12345678' 'हस्ताक्षरित int' और 'sizeof (unsigned int) == 2' में फिट बैठता है, तो' CHAR_BIT' सामान्य से बड़ा है ;-) –

+0

मैं 32-बिट समाज को खराब करने के लिए दोषी ठहराता हूं! –

2

तुम बस bitwise & operator का उपयोग करके उन बाइट्स निकालने की आवश्यकता है। OxFF एक बाइट निकालने के लिए हेक्साडेसिमल मुखौटा है। कृपया यहाँ विभिन्न बिट संचालन को देखो - http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/

एक उदाहरण कार्यक्रम इस प्रकार है:

#include <stdio.h> 

int main() 
{ 
    unsigned int i = 0x1122; 
    unsigned char c[2]; 

    c[0] = i & 0xFF; 
    c[1] = (i>>8) & 0xFF; 

    printf("c[0] = %x \n", c[0]); 
    printf("c[1] = %x \n", c[1]); 
    printf("i = %x \n", i); 

    return 0; 
} 

आउटपुट:

$ gcc 1.c 
$ ./a.out 
c[0] = 22 
c[1] = 11 
i = 1122 
$ 
+1

आप num और 0xFF00 को 8 से अधिक स्थानांतरित करना चाहते थे, है ना? (संख्या और 0xFF00) >> 8। अन्यथा, आपके पास केवल 16-बिट पूर्णांक है जहां निम्न-बाइट शून्य होता है। आपके पास अभी भी बाइट नहीं है। वैकल्पिक रूप से, आप बस स्थानांतरित कर सकते हैं: num >> 8; – abelenky

+0

@abelenky आप सही हैं .. अनदेखा है! –

4

यह वास्तव में अपने लक्ष्य पर निर्भर करता है: तुम क्यों इस परिवर्तित करना चाहते हैं unsigned char पर? इसका जवाब पर निर्भर करता है वहाँ यह करने के लिए कुछ अलग तरीके हैं:

  • काटना: यह क्या सिफारिश की गई थी।यदि आप केवल एक फ़ंक्शन में डेटा निचोड़ने की कोशिश कर रहे हैं जिसके लिए unsigned char की आवश्यकता है, तो बस uchar ch = (uchar)x डालें (लेकिन, निश्चित रूप से, सावधान रहें कि क्या आपकी int बहुत बड़ी है)।

  • विशिष्ट एंडियन: जब आपके गंतव्य को एक विशिष्ट प्रारूप की आवश्यकता होती है तो इसका उपयोग करें। आम तौर पर नेटवर्किंग कोड चार्ज के बड़े एंडियन सरणी में परिवर्तित सब कुछ पसंद करता है:

    int n = sizeof x; 
    for(int y=0; n-->0; y++) 
        ch[y] = (x>>(n*8))&0xff; 
    

    ऐसा करेगा।

  • मशीन एंडियन। इसका उपयोग करें जब कोई अंतहीनता आवश्यकता न हो, और डेटा केवल एक मशीन पर ही होगा। सरणी का क्रम विभिन्न आर्किटेक्चर में बदल जाएगा। लोग आमतौर पर union रों के साथ इस की देखभाल:

    union {int x; char ch[sizeof (int)];} u; 
    u.x = 0xf00 
    //use u.ch 
    

    memcpy साथ:

    :

    uchar ch[sizeof(int)]; 
    memcpy(&ch, &x, sizeof x); 
    

    या कभी खतरनाक सरल कास्टिंग (जो अपरिभाषित व्यवहार है, और कई सिस्टम पर दुर्घटनाओं) के साथ

    char *ch = (unsigned char *)&x;