2010-08-20 6 views
5

मुझे स्ट्रिंग ToLiteral (स्ट्रिंग इनपुट)this post से फ़ंक्शन की आवश्यकता है। इस तरह की है किसी स्ट्रिंग में वर्णों को उनके भागने के दृश्यों में कनवर्ट करें

char *literal = to_literal("asdf\r\n"); 

उपज हैं शाब्दिक ==> "asdf \\ r \\ n"

मैंने चारों ओर गुगल किया है, लेकिन कुछ भी नहीं ढूंढ पाया (अनुमान है कि मुझे गलत शर्तों का उपयोग करना होगा)। हालांकि, मुझे लगता है कि इस कार्यक्षमता वाला एक पुस्तकालय कहीं बाहर होना चाहिए ...

इंटरस्टेस्टिंग उत्तरों के लिए धन्यवाद। गुगलिंग "सी स्ट्रिंग एस्केप फ़ंक्शन" और भी उदाहरण प्राप्त करने की कुंजी प्रतीत होता है और जीएलआईबी g_strescape() प्रदान करता है जो मुझे बिल्कुल वही लगता है जो मुझे चाहिए।

+0

"स्ट्रिंग शाब्दिक" यहां उपयोग करने का सही वाक्यांश नहीं है। आप जो चाहते हैं वह एक ऐसा फ़ंक्शन है जो स्ट्रिंग को बदलता है जैसे कि सी कैप्चर अनुक्रम वाले वर्णों को उन अनुक्रमों के साथ प्रतिस्थापित किया जाता है। –

+0

'literal ==" asdf \ r \ n "' कभी सच नहीं होगा। मुझे लगता है कि आपका मतलब है 'strcmp (शाब्दिक, "asdf \\ r \\ n") == 0'। – jamesdlin

+0

सं। लिटल == "asdf \\ r \\ n" to_literal "asdf \ r \ n" से "asdf \\ r \\ n" में परिवर्तित हो जाएगा। हालांकि, उत्तर से, मैंने सीखा है कि एक बेहतर फ़ंक्शन नाम (सी में) ** char * escape (char *) ** होगा। –

उत्तर

8

की तरह कुछ इस के लिए कोई अंतर्निहित समारोह है हो सकता है, लेकिन आप कर सकते थे कोड़ा एक अप:

/* Expands escape sequences within a C-string 
* 
* src must be a C-string with a NUL terminator 
* 
* dest should be long enough to store the resulting expanded 
* string. A string of size 2 * strlen(src) + 1 will always be sufficient 
* 
* NUL characters are not expanded to \0 (otherwise how would we know when 
* the input string ends?) 
*/ 

void expand_escapes(char* dest, const char* src) 
{ 
    char c; 

    while (c = *(src++)) { 
    switch(c) { 
     case '\a': 
     *(dest++) = '\\'; 
     *(dest++) = 'a'; 
     break; 
     case '\b': 
     *(dest++) = '\\'; 
     *(dest++) = 'b'; 
     break; 
     case '\t': 
     *(dest++) = '\\'; 
     *(dest++) = 't'; 
     break; 
     case '\n': 
     *(dest++) = '\\'; 
     *(dest++) = 'n'; 
     break; 
     case '\v': 
     *(dest++) = '\\'; 
     *(dest++) = 'v'; 
     break; 
     case '\f': 
     *(dest++) = '\\'; 
     *(dest++) = 'f'; 
     break; 
     case '\r': 
     *(dest++) = '\\'; 
     *(dest++) = 'r'; 
     break; 
     case '\\': 
     *(dest++) = '\\'; 
     *(dest++) = '\\'; 
     break; 
     case '\"': 
     *(dest++) = '\\'; 
     *(dest++) = '\"'; 
     break; 
     default: 
     *(dest++) = c; 
    } 
    } 

    *dest = '\0'; /* Ensure nul terminator */ 
} 

ध्यान दें कि मैं (कुछ compilers \e का उपयोग करें और दूसरों \x का उपयोग करें) "भागने" चरित्र को पलायन अनुक्रम का अनुवाद बाहर छोड़ दिया गया है, के बाद से इस सी में मानकीकृत नहीं है। जो भी आप पर लागू होता है उसमें आप जोड़ सकते हैं।

आप एक समारोह है कि आप के लिए अपने गंतव्य बफर आवंटित करना चाहते हैं:

/* Returned buffer may be up to twice as large as necessary */ 
char* expand_escapes_alloc(const char* src) 
{ 
    char* dest = malloc(2 * strlen(src) + 1); 
    expand_escapes(dest, src); 
    return dest; 
} 
+0

कॉलर के लिए यह सब गलत कहने के लिए आसान है - मैं परिणाम को मॉलोक कर दूंगा और इसे – pm100

+2

लौटा दूंगा, यह लिखने का एक और तरीका है, लेकिन लगभग सभी सी मानक लाइब्रेरी स्ट्रिंग फ़ंक्शंस इस तरह से लिखे गए हैं। –

+2

यह किसी भी अन्य गैर-प्रिंटिंग चरित्र को अंडाकार भागने के रूप में एन्कोड करने के लिए 'expand_escapes()' के लिए अनुकूल होगा। यह सामान्य ASCII ईएससी चरित्र को '033' के रूप में संभालता है। बेशक, आपका आउटपुट बफर इनपुट के आकार से 4 गुना तक हो सकता है, इसलिए लौटने से पहले इसे फिर से आवंटित करने के लिए समझदारी हो सकती है। आप लंबाई वाले पैरामीटर के साथ एम्बेडेड एनयूएल अक्षरों को भी संभाल सकते हैं, जहां नकारात्मक लंबाई का मतलब पहले एनयूएल पर बंद होना चाहिए। – RBerteig

0

मुझे लगता है कि आप शब्दावली भ्रमित कर रहे हैं, तो आप इस तरह चार करने के लिए (Acter) एक सूचक को प्रारंभ कर सकते हैं:

char *literal = "asdf\r\n" 

संशोधन: हालांकि, सी स्ट्रिंग्स उदाहरण के लिए भागने उद्धरण उपयोग करने में सक्षम हैं:

char *literal = "\basdf\x1b\r\n\v\t"; 

बाहर प्रिंट होगा कि

<backspace>asdf<escape-character><carriage-return><linefeed><vertical-tab><tab> 

उन पात्रों को कंसोल क्षमताओं के आधार पर नहीं दिखाया जाएगा, आप भागने के लिए एक तीर और टैब के लिए एक अंतर देख सकते हैं ... आप प्रत्येक \ के लिए एक साधारण तर्क का उपयोग करके इसे प्राप्त कर सकते हैं, \ डालें ऐसी है कि वह प्रदर्शित करेगा

asdf\\r\\n 

कुछ निम्न कोड की तरह पर्याप्त होना चाहिए:

void ToLiteral(const char *pStr){ 
    char *p = (char*)pStr; 
    while (*p){ 
     /* if (*p == '\\') putchar('\\'); */ 
     /* PERFORM THE LOOK UP */ 
     putchar(*p++); 
    } 
} 

लेकिन इसे देख, यह सही महसूस नहीं किया था के रूप में सूचक वास्तविक \n और \r तो यह हो सकता है पकड़ रखी थी एक लू का उपयोग करना आसान हो k-अप तालिका भागने दृश्यों के लिए वास्तविक हेक्साडेसिमल कोड तुलना और उचित कोड प्रदर्शित करने के लिए ... लुकअप तालिका इस

struct LookUp{ 
    int codeLiteral; 
    char *equivCodeLiteral; 
}; 

struct LookUp look[] = { { 0xa, "\\r"}, { 0xd, "\\n" }, { 0x9, "\\t" } }; 
+1

संदर्भित पोस्ट को देखते हुए, मुझे नहीं लगता कि यह उनके प्रश्न का उत्तर देता है। वह एक स्ट्रिंग में "asdf \ r \ n" जैसे स्ट्रिंग को कन्वर्ट करना चाहता है जो स्ट्रिंग "asdf \\ r \\ n" – kbrimington

+0

स्ट्रिंग से अपेक्षित आउटपुट का उत्पादन करेगा, हां, यह सच है, लेकिन उस पोस्ट को देखें जिसे वह संदर्भित कर रहा है। वह स्पष्ट रूप से चीजों को अपने संबंधित भागने के क्रम में टैब और न्यूलाइन पसंद करना चाहता है, ऐसा कुछ मुझे लगता है: "हैलो \ nworld" => "हैलो \\ nworld" – Brian

+0

कैविट एम्प्टर: कोड बिल्कुल मूर्ख प्रमाण नहीं है मैं स्वीकार करूंगा - यह मेरे सिर का शीर्ष था ... तो सावधान रहें! :) – t0mm13b

1

मुझे लगता है कि मैं इस तरह रूपांतरण कुछ करना चाहते हैं:

// warning: untested code. 
void make_literal(char const *input, char *output) { 
    // the following two arrays must be maintained in matching order: 
    static char inputs[] = "\a\b\f\n\r\t\v\\\"\'"; 
    static char outputs[] = "abfnrtv\\\"\'"; 

    char *p, *pos; 

    for (;*input;input++) { 
     if (NULL!= (pos=strchr(inputs, *input))) { 
      *output++ = '\\'; 
      *output++ = outputs[pos-inputs]; 
     } 
     else 
      *output++ = *input; 
    } 
    *output = '\0'; 
} 

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

+1

"निम्नलिखित दो सरणी मिलान क्रम में बनाए रखा जाना चाहिए" - इसलिए उन्हें '{}' वाक्यविन्यास के साथ प्रारंभ करें, और लंबवत प्रविष्टियों को पंक्तिबद्ध करें ;-) –

+0

@Steve: यह निश्चित रूप से एक उचित संभावना है ... –

संबंधित मुद्दे