2012-12-24 52 views
8

मैं अपने प्रोग्राम में टुकड़े से एक स्ट्रिंग टुकड़ा बना रहा हूं और वर्तमान में स्ट्रैट() के मिश्रण का उपयोग कर रहा हूं, जब मैं अंत में एक साधारण स्ट्रिंग जोड़ रहा हूं, लेकिन जब एक स्वरूपित स्ट्रिंग जोड़ रहा हूं मैं उपयोग कर रहा हूँ sprintf() जैसे:strcat()

int one = 1; 
sprintf(instruction + strlen(instruction), " number %d", one); 

यह स्वरूपित स्ट्रिंग को श्रेणीबद्ध करने के लिए इस के लिए strcat() अथवा पसंदीदा तरीका क्या है का उपयोग कर सकता है?

+0

सुनिश्चित करें कि आपके पास पर्याप्त स्थान है। – SLaks

उत्तर

12

आपका समाधान काम करेंगे। कॉलिंग स्ट्रेल थोड़ा अजीब है (विशेष रूप से यदि स्ट्रिंग काफी लंबा हो जाता है)।)

char str[MAX_SIZE]; 
char *target = str; 

target += sprintf(target, "%s", str_value); 
target += sprintf(target, "somestuff %d", number); 
if (something) 
{ 
    target += sprintf(target, "%s", str_value2); 
} 
else 
{ 
    target += sprintf(target, "%08x", num2); 
} 

मुझे यकीन है कि strcat ज्यादा sprintf तुलना में अधिक कुशल है नहीं कर रहा हूँ (है: sprintf() लंबाई आप का इस्तेमाल किया है वापस आ जाएगी [strcat नहीं होंगे], तो एक बात आप कर सकते हैं कुछ इस तरह है जब इस तरह इस्तेमाल किया।

संपादित करें: छोटे उदाहरण लिखना चाहिए ...

+0

मेरे लिए काम नहीं करता है :(। जीडीबी में मैं लक्ष्य + = .... जैसी ही रेखा पर देखता हूं, यह बनाता है स्ट्रिंग को बार-बार खाली करें। – Hooli

8

कोई यह संभव नहीं है, लेकिन आप उन सरल तारों पर sprintf() का उपयोग करें और strlen() हर बार फोन करने से बच सकते हैं:

len = 0; 
len += sprintf(buf+len, "%s", str);  
len += sprintf(buf+len, " number %d", one); 
+1

मेरे सुझाव के समान! –

+0

@ मैट्स पीटरसन मैंने पहले जवाब दिया :) – iabdalkader

+0

हां, मैंने एक लंबा उदाहरण लिखा है ...;) –

0

क्या पसंदीदा तरीका है, तुम क्या उपयोग करने के लिए तैयार हैं पर निर्भर करता है। उन सभी मैनुअल (और संभावित रूप से खतरनाक) स्ट्रिंग ऑपरेशंस करने के बजाय, I GLib या GLib के g_strdup_print फ़ंक्शन से GString डेटा संरचना का उपयोग करेगा। आपकी समस्या के लिए, GStringg_string_append_printf फ़ंक्शन प्रदान करता है।

+0

और मुझे लगता है कि यह लगभग sprintf (str + strlen (str), fmt, args ...), ठीक है? –

+0

यह भी [देखभाल करता है] (http: // git। gnome.org/browse/glib/tree/glib/gstring.c#n1154) स्मृति आवंटन/आकार बदलने का। आपका उत्तर एक निश्चित स्ट्रिंग मानता है और एक बार 'str_value2' बहुत बड़ा होता है, तो आप खराब हो जाते हैं। – matthias

+0

यह सच है ... –

0

अपनी ज़रूरत के लिए अपना खुद का रैपर लिखें।

यह करने के लिए एक कॉल इस प्रकार दिखाई देगा: -

result = universal_concatenator(4,result,"numbers are %d %f\n",5,16.045); 
result = universal_concatenator(2,result,"tail_string"); 

आप एक समारोह है, कि, के बारे में चिंता की देखभाल आप sprintf() या strcat() का उपयोग करने की आवश्यकता है जाएगा निर्धारित कर सकते हैं।

/* you should pass the number of arguments 
* make sure the second argument is a pointer to the result always 
* if non formatted concatenation: 
*   call function with number_of_args = 2 
* else 
*   call function with number of args according to format 
*   that is, if five inputs to sprintf(), then 5. 
* 
* NOTE : Here you make an assumption that result has been allocated enough memory to 
*  hold your concatenated string. This assumption holds true for strcat() or 
*  sprintf() of your previous implementation 
*/ 

char* universal_concaternator(int number_of_args,...) 
{ 
    va_list args_list; 
    va_start(args_list,number_of_args); 
    int counter = number_of_args; 
    char *result = va_arg(args_list, char*); 
    char *format; 
    if(counter == 2) /* it is a non-formatted concatenation */ 
    { 
     result = strcat(result,va_arg(args_list,char*)); 
     va_end(args_list); 
     return result; 
    } 
    /* else part - here you perform formatted concatenation using sprintf*/ 
    format = va_arg(args_list,char*); 
    vsprintf(result + strlen(result),format,args_list); 
    va_end(args_list); 
    return result; 
} 

/* dont forget to include the header 
* <stdarg.h> #FOR-ANSI 
* or <varargs.h> #FOR-UNIX 
*/ 

यह सबसे पहले,, यह निर्धारित करना चाहिए, जिनमें से दो में यह (strcat या sprintf) बुलाना चाहिए, तो यह कॉल करने चाहिए, और यह आप के लिए आसान बनाने के -: इस तरह समारोह दिखाई देंगे जो भी आप काम कर रहे हैं उसके वास्तविक तर्क पर ध्यान केंद्रित करें! ऊपर कोड ctrl + c कोड और ctrl + v आपके कोड बेस में।

नोट: मैट का उत्तर लंबे तारों के लिए एक अच्छा विकल्प है। लेकिन छोटी स्ट्रिंग लंबाई (< 250) के लिए, यह करना चाहिए।

+0

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

+0

यह संभव हो सकता है। समारोह ऐसा कर सकता है कुछ tweaks के साथ आप के लिए। यह सुनिश्चित करना कि हम मेमोरी सीमा पार नहीं करते हैं, हालांकि एपीआई के अंदर किए जाने पर बेहतर होता है, मैं यह सुनिश्चित करना चाहता था कि बाहर से। कोड को सरल, तेज बनाता है। यह एक डिजाइन पसंद है। – wlan0

2

प्रत्यक्ष प्रश्न का उत्तर देने के लिए, संभव स्वरूपित तारों को जोड़ने के लिए strcat का उपयोग करने के लिए। तुम बस पहले स्वरूपित स्ट्रिंग का निर्माण करने के लिए है, और फिर आप इसे संलग्न करने के लिए strcat उपयोग कर सकते हैं:

#include <stdio.h> 
#include <string.h> 
int main(void) { 
    char s[100]; 
    char s1[20]; 
    char s2[30]; 
    int n = 42; 
    double x = 22.0/7.0; 

    strcpy(s, "n = "); 
    sprintf(s1, "%d", n); 
    strcat(s, s1); 

    strcat(s, ", x = "); 
    sprintf(s2, "%.6f", x); 
    strcat(s, s2); 

    puts(s); 
    return 0; 
} 

आउटपुट:

n = 42, x = 3.142857 

लेकिन यह एक विशेष रूप से अच्छा तरीका नहीं है।

sprintf एक मौजूदा स्ट्रिंग के अंत तक लिखने के साथ-साथ काम करता है।उदाहरण के लिए Mats's answer और mux's answer देखें। अलग-अलग क्षेत्रों को रखने के लिए उपयोग किए जाने वाले व्यक्तिगत सरणी आवश्यक नहीं हैं, कम से कम इस मामले में नहीं।

और चूंकि यह कोड स्ट्रिंग के अंत का ट्रैक नहीं रखता है, तो प्रदर्शन खराब होने की संभावना है। strcat(s1, s2) को s1 को '\0' को समाप्त करने के लिए पहले स्कैन करना होगा, और फिर इसमें s2 की सामग्री कॉपी करें। अन्य उत्तरों इसे किसी सूचकांक या पॉइंटर को आगे बढ़ाने के बिना स्ट्रिंग के अंत को ट्रैक रखने के लिए आगे बढ़कर इससे बचते हैं।

इसके अलावा, कोड बफर ओवररन्स से बचने के लिए कोई प्रयास नहीं करता है। strncat() यह कर सकता है, लेकिन यह सिर्फ स्ट्रिंग को छोटा करता है; यह आपको नहीं बताता कि इसे छोटा कर दिया गया था। snprintf() एक अच्छा विकल्प है; यह वर्णों की संख्या देता है कि लिखा होगा यदि पर्याप्त स्थान उपलब्ध था। यदि यह आपके द्वारा निर्दिष्ट आकार से अधिक है, तो स्ट्रिंग को छोटा कर दिया गया था।

/* other declarations as above */ 
size_t count; 
count = snprintf(s, sizeof s, "n = %d, x = %.6f", n, x); 
if (count > sizeof s) { 
    /* the string was truncated */ 
} 

और कई तार (मान लीजिए, यदि कुछ सशर्त या बार-बार जोड़ दिए जाते हैं), तो आपको अन्य उत्तर में तरीकों लक्ष्य स्ट्रिंग के अंत का ट्रैक रखने के लिए उपयोग कर सकते संलग्न करने के लिए।

तो हां, स्वरूपित स्ट्रिंग को strcat() के साथ जोड़ना संभव है। यह सिर्फ एक अच्छा विचार होने की संभावना नहीं है।