सी

2009-10-12 16 views
6

में हेक्स से चार सरणी हेक्स मानों की एक स्ट्रिंग को देखते हुए यानी उदा। "0011223344" ताकि 0x00, 0x11 इत्यादिसी

मैं इन मानों को चार सरणी में कैसे जोड़ूं?

समतुल्य कहने के लिए:

char array[4] = { 0x00, 0x11 ... }; 

उत्तर

-3

पहले, अपने प्रश्न बहुत ही सटीक नहीं है। क्या स्ट्रिंग std::string या char बफर है? संकलन समय पर सेट करें?

गतिशील स्मृति लगभग निश्चित रूप से आपका उत्तर है।

char* arr = (char*)malloc(numberOfValues); 

उसके बाद, आप इनपुट के माध्यम से चलना, और सरणी को असाइन कर सकें।

+1

यह एक std :: स्ट्रिंग नहीं है - यह सी है और केवल एक ही प्रकार की स्ट्रिंग है। –

+2

@ पॉल: आप अपने उत्तर के बारे में क्या सोचते हैं? सवाल यह है कि 'इनपुट के माध्यम से कैसे चलना है और इसे एक सरणी में असाइन करना' है ... जिसे आप पाठक के लिए अभ्यास के रूप में सावधानीपूर्वक छोड़ देते हैं। –

+1

@ जोन: (1) सी और सी ++ कभी-कभी भ्रमित हो जाते हैं, (2) मैं पूछताछ करने वालों के लिए व्यायाम के रूप में गृहकार्य प्रश्न छोड़ देता हूं, और (3) मैं ओपी से प्रतिक्रियाओं की उम्मीद कर रहा था ताकि एक देने पर ध्यान दिया जा सके बेहतर जवाब, लेकिन उसने "पूछो और चलाया" किया। –

16

आप 4 बाइट सरणी में डेटा के 5 बाइट्स फिट नहीं कर सकते हैं; जो बफर ओवरफ्लो की ओर जाता है।

आप एक स्ट्रिंग में हेक्स अंक है, तो आप sscanf() और एक पाश का उपयोग कर सकते हैं:

#include <stdio.h> 
#include <ctype.h> 

int main() 
{ 
    const char *src = "0011223344"; 
    char buffer[5]; 
    char *dst = buffer; 
    char *end = buffer + sizeof(buffer); 
    unsigned int u; 

    while (dst < end && sscanf(src, "%2x", &u) == 1) 
    { 
     *dst++ = u; 
     src += 2; 
    } 

    for (dst = buffer; dst < end; dst++) 
     printf("%d: %c (%d, 0x%02x)\n", dst - buffer, 
       (isprint(*dst) ? *dst : '.'), *dst, *dst); 

    return(0); 
} 

ध्यान दें कि स्ट्रिंग एक शून्य-बाइट के साथ शुरू मुद्रण देखभाल की आवश्यकता है; अधिकांश ऑपरेशन पहले नल बाइट पर समाप्त होते हैं। ध्यान दें कि इस कोड ने बफर को निरस्त नहीं किया है; यह स्पष्ट नहीं है कि शून्य समाप्ति वांछनीय है, और बफर में पर्याप्त जगह नहीं है जिसे मैंने टर्मिनल नल जोड़ने के लिए घोषित किया है (लेकिन यह आसानी से तय किया गया है)। एक सभ्य मौका है कि यदि कोड को सबराउटिन के रूप में पैक किया गया था, तो उसे परिवर्तित स्ट्रिंग की लंबाई वापस करने की आवश्यकता होगी (हालांकि आप यह भी तर्क दे सकते हैं कि यह दो से विभाजित स्रोत स्ट्रिंग की लंबाई है)।

+2

इस उत्तर ने मुझे बचाया !!! काम की। Arduino के लिए भी बहुत अच्छा काम करता है, बस printf सेक्शन – frazras

3

तो स्ट्रिंग सही है और उसकी सामग्री तो रखने के लिए मैं इसे इस तरह से करना होगा की कोई जरूरत नहीं:

#define hex(c) ((*(c)>='a')?*(c)-'a'+10:(*(c)>='A')?*(c)-'A'+10:*(c)-'0') 

void hex2char(char *to){ 
    for(char *from=to; *from; from+=2) *to++=hex(from)*16+hex(from+1); 
    *to=0; 
} 

संपादित करें 1: क्षमा करें, मैं पत्र वायुसेना (वायुसेना)

साथ गणना करने के लिए भूल जाते हैं

संपादित करें 2:

#include <string.h> 

int xdigit(char digit){ 
    int val; 
     if('0' <= digit && digit <= '9') val = digit -'0'; 
    else if('a' <= digit && digit <= 'f') val = digit -'a'+10; 
    else if('A' <= digit && digit <= 'F') val = digit -'A'+10; 
    else         val = -1; 
    return val; 
} 

int xstr2str(char *buf, unsigned bufsize, const char *in){ 
    if(!in) return -1; // missing input string 

    unsigned inlen=strlen(in); 
    if(inlen%2 != 0) return -2; // hex string must even sized 

    for(unsigned i=0; i<inlen; i++) 
    if(xdigit(in[i])<0) return -3; // bad character in hex string 

    if(!buf || bufsize<inlen/2+1) return -4; // no buffer or too small 

    for(unsigned i=0,j=0; i<inlen; i+=2,j++) 
    buf[j] = xdigit(in[i])*16 + xdigit(in[i+1]); 

    buf[inlen/2] = '\0'; 
    return inlen/2+1; 
}

परीक्षण::

#include <stdio.h> 

char buf[100] = "test"; 

void test(char *buf, const char *s){ 
    printf("%3i=xstr2str(\"%s\", 100, \"%s\")\n", xstr2str(buf, 100, s), buf, s); 
} 

int main(){ 
    test(buf,  (char*)0 ); 
    test(buf,  "123"  ); 
    test(buf,  "3x"  ); 
    test((char*)0, ""  ); 
    test(buf,  ""  ); 
    test(buf,  "3C3e" ); 
    test(buf,  "3c31323e"); 

    strcpy(buf, "616263" ); test(buf, buf); 
}
मैं एक और अधिक पंडिताऊ कोड लिखने का प्रयास किया

परिणाम:

-1=xstr2str("test", 100, "(null)") 
-2=xstr2str("test", 100, "123") 
-3=xstr2str("test", 100, "3x") 
-4=xstr2str("(null)", 100, "") 
    1=xstr2str("", 100, "") 
    3=xstr2str("", 100, "3C3e") 
    5=xstr2str("", 100, "3c31323e") 
    4=xstr2str("abc", 100, "abc") 
+0

छोड़ दें यह मानता है कि आपको स्ट्रिंग को संशोधित करने की अनुमति है, और सीटू में अनुवाद करता है, और नल परिवर्तित स्ट्रिंग को समाप्त करता है। चूंकि पहला बाइट शून्य है, इसलिए आपको शायद परिवर्तित वर्णों की संख्या वापस करने की आवश्यकता है। –

+0

आप सच हैं, लेकिन सवाल आवश्यकताओं को तैयार नहीं करता है, इसलिए यह कोड पर्याप्त है ;-) – sambowry

+0

आप 9 से ऊपर हेक्स अंकों का समर्थन करने पर भी विचार करना चाहेंगे।यदि काम करने के लिए आवश्यक एकमात्र स्ट्रिंग प्रश्न में दी गई है, तो स्पष्ट रूप से सबसे संक्षिप्त उत्तर 'char array [] = {0, 17, 34, 51, 68} है; '। लेकिन मुझे लगता है जब प्रश्नकर्ता ने कहा "यानी", वह वास्तव में "उदा।" –

0

Fatalfloor ...

तरीके यह करने के लिए की एक जोड़ी रहे हैं ... पहले, आप memcpy() का उपयोग चार सरणी में सटीक प्रतिनिधित्व कॉपी करने के लिए कर सकते हैं।

आप बिट स्थानांतरण और बिट मास्किंग तकनीकों का भी उपयोग कर सकते हैं। मुझे लगता है कि यह वही है जो आपको करने की ज़रूरत है क्योंकि यह होमवर्क समस्या की तरह लगता है।

आखिरकार, आप आवश्यक स्मृति स्थान की प्रतिलिपि बनाने के लिए कुछ फैंसी पॉइंटर इंडिकेशन का उपयोग कर सकते हैं।

इन सभी पद्धतियों का यहाँ विस्तृत कर रहे हैं:

Store an int in a char array?

+0

क्या आप स्पष्ट करना चाहते हैं कि memcpy() का उपयोग कैसे किया जा सकता है? –

3

मैं कुछ इस तरह करना होगा;

// Convert from ascii hex representation to binary 
// Examples; 
// "00" -> 0 
// "2a" -> 42 
// "ff" -> 255 
// Case insensitive, 2 characters of input required, no error checking 
int hex2bin(const char *s) 
{ 
    int ret=0; 
    int i; 
    for(i=0; i<2; i++) 
    { 
     char c = *s++; 
     int n=0; 
     if('0'<=c && c<='9') 
      n = c-'0'; 
     else if('a'<=c && c<='f') 
      n = 10 + c-'a'; 
     else if('A'<=c && c<='F') 
      n = 10 + c-'A'; 
     ret = n + ret*16; 
    } 
    return ret; 
} 

int main() 
{ 
    const char *in = "0011223344"; 
    char out[5]; 
    int i; 

    // Hex to binary conversion loop. For example; 
    // If in="0011223344" set out[] to {0x00,0x11,0x22,0x33,0x44} 
    for(i=0; i<5; i++) 
    { 
     out[i] = hex2bin(in); 
     in += 2; 
    } 
    return 0; 
} 
0

एक सबसे अच्छा तरीका दें:

हेक्स संख्यात्मक मान को स्ट्रिंग है, यानी str [] = "+००११२२३३४४" 0x0011223344 मूल्य, का उपयोग

value = strtoul(string, NULL, 16); // or strtoull() 

किया। यदि 0x00 की शुरुआत की आवश्यकता है, तो नीचे देखें।

हालांकि LITTLE_ENDIAN प्लेटफार्मों के लिए, प्लस: सरणी, मूल्य 0x11223344 चार को हेक्स मूल्य आगमन [N] = {0x00, 0x11, ...}

unsigned long *hex = (unsigned long*)arr; 
*hex = htonl(value); 
// you'd like to remove any beginning 0x00 
char *zero = arr; 
while (0x00 == *zero) { zero++; } 
if (zero > arr) memmove(zero, arr, sizeof(arr) - (zero - arr)); 

किया चार करने के लिए।

नोट्स: एक 64 बिट्स हेक्स चार एक 32-बिट सिस्टम पर आगमन के लिए लंबी स्ट्रिंग परिवर्तित करने के लिए, आप अहस्ताक्षरित लंबे बजाय अहस्ताक्षरित लंबे का उपयोग करना चाहिए, और htonl पर्याप्त नहीं है, तो यह अपने आप के रूप में नीचे क्योंकि हो सकता है कर वहाँ कोई htonll, htonq या hton64 आदि है:

#if __KERNEL__ 
    /* Linux Kernel space */ 
    #if defined(__LITTLE_ENDIAN_BITFIELD) 
     #define hton64(x) __swab64(x) 
    #else 
     #define hton64(x) (x) 
    #endif 
#elif defined(__GNUC__) 
    /* GNU, user space */ 
    #if __BYTE_ORDER == __LITTLE_ENDIAN 
     #define hton64(x) __bswap_64(x) 
    #else 
     #define hton64(x) (x) 
    #endif 
#elif 
     ... 
#endif 

#define ntoh64(x) hton64(x) 

http://effocore.googlecode.com/svn/trunk/devel/effo/codebase/builtin/include/impl/sys/bswap.h

+0

अधिकतम हेक्स स्ट्रिंग लंबाई समर्थित: char शुरू होने पर 16 बाइट/वर्ण '0' नहीं है। – Test

0
{ 
    char szVal[] = "268484927472"; 
    char szOutput[30]; 

    size_t nLen = strlen(szVal); 
    // Make sure it is even. 
    if ((nLen % 2) == 1) 
    { 
     printf("Error string must be even number of digits %s", szVal); 
    } 

    // Process each set of characters as a single character. 
    nLen >>= 1; 
    for (size_t idx = 0; idx < nLen; idx++) 
    { 
     char acTmp[3]; 
     sscanf(szVal + (idx << 1), "%2s", acTmp); 
     szOutput[idx] = (char)strtol(acTmp, NULL, 16); 
    } 
} 
0

देख मैं एक ही बात के लिए खोज रहा था और एक बहुत पढ़ने के बाद, अंत में इस समारोह का निर्माण किया। सोचा कि यह मदद कर सकता है,

// in = "63 09 58 81" 
void hexatoascii(char *in, char* out, int len){ 
    char buf[5000]; 
    int i,j=0; 
    char * data[5000]; 
    printf("\n size %d", strlen(in)); 
    for (i = 0; i < strlen(in); i+=2) 
    { 
     data[j] = (char*)malloc(8); 
     if (in[i] == ' '){ 
      i++; 
     } 
     else if(in[i + 1] == ' '){ 
      i++; 
     } 
     printf("\n %c%c", in[i],in[i+1]); 
     sprintf(data[j], "%c%c", in[i], in[i+1]); 
     j++; 
    } 

    for (i = 0; i < j-1; i++){ 
     int tmp; 
     printf("\n data %s", data[i]); 
     sscanf(data[i], "%2x", &tmp); 
     out[i] = tmp; 
    } 
    //printf("\n ascii value of hexa %s", out); 
} 
0

मान लें कि यह एक छोटा-सा एशियन मंच है। शायद ओ पी का मतलब "स्ट्रिंग" "चार की सरणी" के बजाय .. हम चार के जोड़े के साथ काम करते हैं और मास्किंग .. x 16 का नोट shiftyness सा ..

/* not my original work, on stacko somewhere ? */ 

for (i=0;i < 4;i++) { 

    char a = string[2 * i]; 
    char b = string[2 * i + 1]; 

    array[i] = (((encode(a) * 16) & 0xF0) + (encode(b) & 0x0F)); 
} 

और समारोह एनकोड() परिभाषित किया गया है। ..

unsigned char encode(char x) {  /* Function to encode a hex character */ 
/**************************************************************************** 
* these offsets should all be decimal ..x validated for hex..    * 
****************************************************************************/ 
    if (x >= '0' && x <= '9')   /* 0-9 is offset by hex 30 */ 
     return (x - 0x30); 
    else if (x >= 'a' && x <= 'f') /* a-f offset by hex 57 */ 
     return(x - 0x57); 
    else if (x >= 'A' && x <= 'F') /* A-F offset by hex 37 */ 
     return(x - 0x37); 
} 

यह दृष्टिकोण कहीं और तैरता है, यह मेरा मूल काम नहीं है, लेकिन यह पुराना है। शुद्धवादियों द्वारा पसंद नहीं किया गया क्योंकि यह गैर-पोर्टेबल है, लेकिन विस्तार छोटा होगा।