दिलचस्प पोस्ट
सी # में गहरी और उथले क्लोन बनाने का एक बेहतर तरीका है? एंड्रॉइड कस्टम लेआउट – ऑन ड्रा () को कभी भी कॉल नहीं किया जाता है कैसे jquery / javascript के माध्यम से <head> में कुछ भी जोड़ने के लिए? सरणी की सूची को एक बहुआयामी सरणी में कनवर्ट कैसे करें सी ++ में स्थिर सरणी बनाम गतिशील सरणी कंसोल में कैसे लिखें। एमएसटीईस्ट टेस्ट के निष्पादन के दौरान मैं UIScrollView ज़ूम के बाद कैसे रीसेट करूं? आराम – जटिल अनुप्रयोग "एक संभावित खतरनाक अनुरोध प्राप्त करना। क्लाइंट (&) से पाथ मान पाया गया था" आर में एक अन्य समारोह के भीतर ggplot () का उपयोग करें जर्सी क्लाइंट एपीआई – प्रमाणीकरण पायथन – कैलेंडर.टाइमगाम () बनाम time.mktime () सी ++ में प्लेसमेंट हटाए जाने की अभिव्यक्ति क्यों नहीं है? जीयूआई एमवीसी को फिर से लिखने के बाद काम नहीं कर रहा है एनएमपी ने अंगुलर जेएस फोनकैट एप्लिकेशन में समस्याएं शुरू की

मैं सी में const / literal तार को कैसे जोड़ूं?

मैं सी में काम कर रहा हूं, और मुझे कुछ चीजों को जोड़ना होगा।

अभी मेरे पास यह है:

message = strcat("TEXT ", var); message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar)); 

अब अगर आपके पास सी में अनुभव है तो मुझे यकीन है कि आपको पता है कि यह आपको एक विभाजन त्रुटि देता है जब आप इसे चलाने का प्रयास करते हैं तो मैं उसके आसपास कैसे काम करूं?

Solutions Collecting From Web of "मैं सी में const / literal तार को कैसे जोड़ूं?"

सी में, "स्ट्रिंग्स" सिर्फ सादे char हैं इसलिए, आप उन्हें सीधे अन्य "तार" के साथ जोड़ नहीं सकते हैं

आप strcat फ़ंक्शन का उपयोग कर सकते हैं, जो तार द्वारा स्ट्रिंग के अंत तक इंगित की गई स्ट्रिंग को जोड़ता है:

 char *strcat(char *dest, const char *src); 

यहां cplusplus.com से एक उदाहरण है :

 char str[80]; strcpy(str, "these "); strcat(str, "strings "); strcat(str, "are "); strcat(str, "concatenated."); 

पहले पैरामीटर के लिए, आपको गंतव्य बफ़र को स्वयं प्रदान करना होगा। गंतव्य बफर एक चार सरणी बफ़र होना चाहिए। उदाहरण: char buffer[1024];

सुनिश्चित करें कि पहले पैरामीटर में उसमें संग्रह करने का प्रयास करने के लिए पर्याप्त स्थान है। यदि आप के लिए उपलब्ध है, तो ये कार्यों का उपयोग करने के लिए सुरक्षित है: strcpy_s और strcat_s जहां आपको स्पष्ट रूप से गंतव्य बफ़र का आकार निर्दिष्ट करना होगा।

नोट : एक स्ट्रिंग शब्दशः बफर के रूप में उपयोग नहीं किया जा सकता, क्योंकि यह स्थिर है इस प्रकार, आपको हमेशा बफर के लिए एक चार सरणी आवंटित करना होगा

वापसी के मूल्य को आसानी से अनदेखा किया जा सकता है, यह केवल वही सूचक देता है जैसा कि पहले तर्क के रूप में पारित किया गया था। यह सुविधा के लिए है, और आपको कोड की एक पंक्ति में कॉल करने की अनुमति देता है:

 strcat(strcat(str, foo), bar); 

तो आपकी समस्या का हल हो सकता है:

 char *foo = "foo"; char *bar = "bar"; char str[80]; strcpy(str, "TEXT "); strcat(str, foo); strcat(str, bar); 

सी कोड में strcat का उपयोग करने से बचें साफ और, सबसे महत्वपूर्ण, सबसे सुरक्षित तरीका snprintf का उपयोग snprintf :

 char buf[256]; snprintf(buf, sizeof buf, "%s%s%s%s", str1, str2, str3, str4); 

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

इसके अलावा malloc और realloc उपयोगी होते हैं यदि आप समय से आगे नहीं जानते हैं कि कितने स्ट्रिंग को एक साथ जोड़ा जा रहा है।

 #include <stdio.h> #include <string.h> void example(const char *header, const char **words, size_t num_words) { size_t message_len = strlen(header) + 1; /* + 1 for terminating NULL */ char *message = (char*) malloc(message_len); strncat(message, header, message_len); for(int i = 0; i < num_words; ++i) { message_len += 1 + strlen(words[i]); /* 1 + for separator ';' */ message = (char*) realloc(message, message_len); strncat(strncat(message, ";", message_len), words[i], message_len); } puts(message); free(message); } 

लोग, str n cpy (), str n cat (), या s n printf () का उपयोग करें
आपके बफ़र स्थान से अधिक होने पर स्मृति में जो कुछ भी होता है, उसे मिटा दिया जाएगा!
(और पीछे की ओर शून्य '\ 0' चरित्र के लिए स्थान की अनुमति देने के लिए याद रखना!)

स्ट्रिंग को संकलन समय पर भी जोड़ा जा सकता है।

 #define SCHEMA "test" #define TABLE "data" const char *table = SCHEMA "." TABLE ; // note no + or . or anything const char *qry = // include comments in a string " SELECT * " // get all fields " FROM " SCHEMA "." TABLE /* the table */ " WHERE x = 1 " /* the filter */ ; 

उत्पादन बफर को प्रारंभ करने के लिए मत भूलना Strcat का पहला तर्क जिसके परिणामस्वरूप स्ट्रिंग के लिए आवंटित पर्याप्त अतिरिक्त स्थान के साथ एक रिक्त समाप्त स्ट्रिंग होना चाहिए:

 char out[1024] = ""; // must be initialized strcat( out, null_terminated_string ); // null_terminated_string has less than 1023 chars 

कंटेटेड स्ट्रिंग के लिए पर्याप्त अंतर रखने के लिए सक्षम होने की आवश्यकता है। तो परिणाम प्राप्त करने के लिए पर्याप्त स्थान के साथ एक बफर आवंटित करें।

 char bigEnough[64] = ""; strcat(bigEnough, "TEXT"); strcat(bigEnough, foo); /* and so on */ 

strcat () पहले तर्क के साथ दूसरे तर्क को जोड़ना होगा, और परिणाम को पहले तर्क में संग्रहीत करेगा, लौटाए गए चार * केवल यह पहला तर्क है, और केवल आपकी सुविधा के लिए।

आपको एक नया आवंटित स्ट्रिंग नहीं मिलती है जिसमें पहले और दूसरे तर्क के साथ सम्मिलित होता है, जो मुझे लगता था कि आपके कोड के आधार पर अनुमान लगाया गया था।

जैसा कि लोगों ने बताया कि स्ट्रिंग हैंडलिंग में बहुत सुधार हुआ है। तो आप सी-स्टाइल स्ट्रिंग्स के बजाय C ++ स्ट्रिंग लाइब्रेरी का उपयोग कैसे करना सीख सकते हैं। हालांकि यहाँ शुद्ध सी में एक समाधान है

 #include <string.h> #include <stdio.h> #include <stdlib.h> void appendToHello(const char *s) { const char *const hello = "hello "; const size_t sLength = strlen(s); const size_t helloLength = strlen(hello); const size_t totalLength = sLength + helloLength; char *const strBuf = malloc(totalLength + 1); if (strBuf == NULL) { fprintf(stderr, "malloc failed\n"); exit(EXIT_FAILURE); } strcpy(strBuf, hello); strcpy(strBuf + helloLength, s); puts(strBuf); free(strBuf); } int main (void) { appendToHello("blah blah"); return 0; } 

मुझे यकीन नहीं है कि यह सही / सुरक्षित है, लेकिन अभी मुझे एएनएससी सी में ऐसा करने का बेहतर तरीका नहीं मिल सका।

सीमित बफर आकार के बिना इसे करने का सर्वोत्तम तरीका asprintf () का उपयोग कर रहा है

 char* concat(const char* str1, const char* str2) { char* result; asprintf(&result, "%s%s", str1, str2); return result; } 

स्ट्रिंग लीटरल्स को संशोधित करने का प्रयास करने के लिए यह अपरिभाषित व्यवहार है, जो कुछ ऐसा है:

 strcat ("Hello, ", name); 

करने का प्रयास करेंगे यह स्ट्रिंग की "Hello, " स्ट्रिंग के अंत में name स्ट्रिंग पर हमला करने की कोशिश करेगा, जो कि अच्छी तरह से परिभाषित नहीं है।

यह कुछ प्रयास करें यह आपको प्राप्त करने की कोशिश करते हुए प्राप्त होता है:

 char message[1000]; strcpy (message, "TEXT "); strcat (message, var); 

यह एक बफर क्षेत्र बनाता है जिसे संशोधित करने की अनुमति है और उसके बाद स्ट्रिंग को शाब्दिक और अन्य पाठ दोनों में प्रतिलिपि बनाता है बस बफर ओवरफ्लो के साथ सावधान रहें यदि आप इनपुट डेटा को नियंत्रित करते हैं (या पहले से जांचते हैं), मेरे पास निश्चित लम्बाई बफ़र्स का उपयोग करना ठीक है

अन्यथा, आप ढेर से पर्याप्त मेमोरी आवंटित करने के लिए शमन की रणनीतियों का उपयोग करना चाहिए जिससे कि आप उसे संभाल सकें। दूसरे शब्दों में, ऐसा कुछ:

 const static char TEXT[] = "TEXT "; // Make *sure* you have enough space. char *message = malloc (sizeof(TEXT) + strlen(var) + 1); if (message == NULL) handleOutOfMemoryIntelligently(); strcpy (message, TEXT); strcat (message, var); // Need to free message at some point after you're done with it. 

आप अपना स्वयं का फ़ंक्शन लिख सकते हैं जो strcat() को समान करता है strcat() लेकिन वह कुछ भी नहीं बदलता है:

 #define MAX_STRING_LENGTH 1000 char *strcat_const(const char *str1,const char *str2){ static char buffer[MAX_STRING_LENGTH]; strncpy(buffer,str1,MAX_STRING_LENGTH); if(strlen(str1) < MAX_STRING_LENGTH){ strncat(buffer,str2,MAX_STRING_LENGTH - strlen(buffer)); } buffer[MAX_STRING_LENGTH - 1] = '\0'; return buffer; } int main(int argc,char *argv[]){ printf("%s",strcat_const("Hello ","world")); //Prints "Hello world" return 0; } 

यदि दोनों स्ट्रिंग 1000 अक्षरों से अधिक लंबे हैं, तो यह स्ट्रिंग को 1000 वर्णों में कट जाएगा। आप अपनी आवश्यकताओं के अनुरूप MAX_STRING_LENGTH के मूल्य को बदल सकते हैं।

यह मानते हुए कि आपके पास चार * स्थान के बजाय एक चार [निर्धारित_आकार] है, तो आप एक ही रचनात्मक मैक्रो का उपयोग एक बार में <<cout<<like साथ करने के लिए कर सकते हैं ("बल्कि% s असंबद्ध% s \ n" "से", "प्रिंटफ़ शैली प्रारूप") यदि आप एम्बेडेड सिस्टम के साथ काम कर रहे हैं, तो यह विधि आपको snprintf() को छोड़ने और snprintf() जैसे कार्यों के बड़े *printf snprintf() परिवार को छोड़ने की अनुमति देगा (इस बारे में * printf के बारे में शिकायत करने से dietlibc रहता है)

 #include <unistd.h> //for the write example //note: you should check if offset==sizeof(buf) after use #define strcpyALL(buf, offset, ...) do{ \ char *bp=(char*)(buf+offset); /*so we can add to the end of a string*/ \ const char *s, \ *a[] = { __VA_ARGS__,NULL}, \ **ss=a; \ while((s=*ss++)) \ while((*s)&&(++offset<(int)sizeof(buf))) \ *bp++=*s++; \ if (offset!=sizeof(buf))*bp=0; \ }while(0) char buf[256]; int len=0; strcpyALL(buf,len, "The config file is in:\n\t",getenv("HOME"),"/.config/",argv[0],"/config.rc\n" ); if (len<sizeof(buf)) write(1,buf,len); //outputs our message to stdout else write(2,"error\n",6); //but we can keep adding on because we kept track of the length //this allows printf-like buffering to minimize number of syscalls to write //set len back to 0 if you don't want this behavior strcpyALL(buf,len,"Thanks for using ",argv[0],"!\n"); if (len<sizeof(buf)) write(1,buf,len); //outputs both messages else write(2,"error\n",6); 
  • नोट 1, आप आम तौर पर इस तरह argv [0] का उपयोग नहीं करेंगे – सिर्फ एक उदाहरण
  • नोट 2, आप किसी भी फ़ंक्शन का उपयोग कर सकते हैं जो स्ट्रॉन्शन प्रकार के लिए पूर्णांक को परिवर्तित करने के लिए अस्थायी कार्यों जैसे इतोआ () जैसे चार * आउटपुट करता है
  • नोट 3, यदि आप पहले से ही अपने प्रोग्राम में printf का उपयोग कर रहे हैं, तो snprintf () का उपयोग नहीं करने का कोई कारण नहीं है, क्योंकि संकलित कोड बड़ा होगा (लेकिन इनलाइन और बहुत तेज)
 int main() { char input[100]; gets(input); char str[101]; strcpy(str, " "); strcat(str, input); char *p = str; while(*p) { if(*p == ' ' && isalpha(*(p+1)) != 0) printf("%c",*(p+1)); p++; } return 0; } 

आप एक स्ट्रिंग को उस पते में कॉपी करने का प्रयास कर रहे हैं जो स्थिर रूप से आवंटित है। आपको एक बफर में बिल्ली की जरूरत है

विशेष रूप से:

… कटाव …

गंतव्य

 Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string. 

… कटाव …

http://www.cplusplus.com/reference/clibrary/cstring/strcat.html

यहां एक उदाहरण यहां भी है।

यदि आपको सी में अनुभव है तो आप देखेंगे कि तार केवल चार सरणियां हैं जहां अंतिम वर्ण एक निरर्थक वर्ण है

अब यह काफी असुविधाजनक है क्योंकि आपको कुछ जोड़ने के लिए अंतिम वर्ण ढूंढना होगा। आपके लिए ऐसा करना होगा।

तो एक अशक्त चरित्र के लिए पहली तर्क के माध्यम से खोजता है फिर यह दूसरी तर्क की सामग्री के साथ इसे बदल देगा (जब तक कि एक अशक्त में समाप्त होता नहीं)

अब हम आपके कोड के माध्यम से चलते हैं:

 message = strcat("TEXT " + var); 

यहां आप "TEXT" पाठ के सूचक को कुछ जोड़ रहे हैं ("TEXT" का प्रकार const char *। एक सूचक है।)।

वह आम तौर पर काम नहीं करेगा "TEXT" सरणी को संशोधित करने के साथ काम नहीं करेगा क्योंकि यह आमतौर पर एक निरंतर खंड में रखा जाता है।

 message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar)); 

इससे बेहतर काम हो सकता है, सिवाय इसके कि आप फिर से स्थैतिक ग्रंथों को संशोधित करने का प्रयास कर रहे हैं। strcat परिणाम के लिए नई स्मृति आवंटित नहीं है

मैं इसके बजाय कुछ ऐसा करने का प्रस्ताव करता हूं:

 sprintf(message2, "TEXT %s TEXT %s", foo, bar); 

इसके विकल्पों की जांच करने के लिए sprintf के दस्तावेज़ीकरण पढ़ें।

और अब एक महत्वपूर्ण मुद्दा:

सुनिश्चित करें कि बफर में पाठ और नल चरित्र रखने के लिए पर्याप्त स्थान है। आपकी मदद कर सकते हैं, जो कुछ फ़ंक्शंस हैं, जैसे, strncat और printf के विशेष संस्करण जो आपके लिए बफ़र को आवंटित करते हैं। बफर आकार को सुनिश्चित नहीं करने से स्मृति भ्रष्टाचार और दूरस्थ रूप से शोषण करने वाली बग को जन्म दिया जाएगा।

यह मेरा समाधान था

 #include <stdlib.h> #include <stdarg.h> char *strconcat(int num_args, ...) { int strsize = 0; va_list ap; va_start(ap, num_args); for (int i = 0; i < num_args; i++) strsize += strlen(va_arg(ap, char*)); char *res = malloc(strsize+1); strsize = 0; va_start(ap, num_args); for (int i = 0; i < num_args; i++) { char *s = va_arg(ap, char*); strcpy(res+strsize, s); strsize += strlen(s); } va_end(ap); res[strsize] = '\0'; return res; } 

लेकिन आपको निर्दिष्ट करना होगा कि आप कितने तार जोड़ना चाहते हैं

 char *str = strconcat(3, "testing ", "this ", "thing"); 

इस के समान कुछ प्रयास करें:

 #include <stdio.h> #include <string.h> int main(int argc, const char * argv[]) { // Insert code here... char firstname[100], secondname[100]; printf("Enter First Name: "); fgets(firstname, 100, stdin); printf("Enter Second Name: "); fgets(secondname,100,stdin); firstname[strlen(firstname)-1]= '\0'; printf("fullname is %s %s", firstname, secondname); return 0; }