मैं सी में कॉन्स्टेंट / शाब्दिक तार कैसे समतल कर सकता हूं?


347

मैं सी में काम कर रहा हूं, और मुझे कुछ चीजों को बदलना है।

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

message = strcat("TEXT ", var);

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

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


6
मैं आपको सुझाव देना चाहूंगा कि आप स्ट्रैकट के बजाय स्ट्रक्लेट का उपयोग करें! gratisoft.us/todd/papers/strlcpy.html
activout.se

3
मैं उस सुझाव को दोहराना चाहूंगा। Strcat बफर अतिप्रवाह शोषण के लिए भेद्यता का कारण बनता है। कोई व्यक्ति आपके प्रोग्राम डेटा को दे सकता है जिसके कारण वह मनमाना कोड निष्पादित करता है।
ब्रायन

जवाबों:


388

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

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

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(strcat(str, foo), bar);

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

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

66
क्या आप बोल्ड, "कृपया बहुत सावधान रहें ..." इस पर जोर नहीं दिया जा सकता। Strcat, strcpy, और sprintf का दुरुपयोग अस्थिर / असुरक्षित सॉफ़्टवेयर का दिल है।
कुर्सी

12
चेतावनी: जैसा कि लिखा गया है, यह कोड बफर अतिप्रवाह कारनामों के लिए आपके कोड में एक विशाल, अंतराल छेद छोड़ देगा।
ब्रायन

11
उपरोक्त उदाहरण में कोई बफर अतिप्रवाह शोषण संभव नहीं है। और हाँ, मैं सामान्य रूप से सहमत हूं कि मैं उपरोक्त उदाहरण का उपयोग फू और बार की अनिश्चित स्ट्रिंग लंबाई के लिए नहीं करूंगा।
ब्रायन आर। बॉन्डी

13
@psihodelia: यह भी मत भूलो कि चम्मच कांटे से बहुत बेहतर हैं! इसलिए हमेशा एक चम्मच का उपयोग करना सुनिश्चित करें!
ब्रायन आर। बॉन्डी

20
दूसरे @dolmen के लिए, जोएल स्पोलस्की ने इस मुद्दे पर काफी विस्तृत लेख लिखा है । एक अनिवार्य पढ़ना चाहिए। ;-)
पीटर।

247

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

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

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


3
चेकर्स, वह आकार के तर्क के "buf" के आसपास कोष्ठकों के बारे में बात कर रहे थे। यदि तर्क एक अभिव्यक्ति है, तो उनकी आवश्यकता नहीं है। लेकिन मुझे समझ नहीं आ रहा है कि आप क्यों निराश हैं। मुझे लगता है कि आपका उत्तर सबसे अच्छा है, भले ही यह c99 है। (हो सकता है की वजह से है कि वे इससे सहमत नहीं lamers!) +1
Johannes Schaub - litb

4
sizeof () केवल यहाँ char buf [...] के लिए काम करता है। नहीं के लिए चार * buf = malloc (...)। सरणियों और संकेत के बीच बहुत अंतर नहीं हैं, लेकिन यह उनमें से एक है!
मिस्टर रीव

2
इसके अलावा, वह संघटन करने की कोशिश कर रहा है। कॉनटेटनेटिंग का उपयोग करके snprintf()एक बीआईजी नंबर नो है।
लियोनार्डो हरेरा

5
@ श्री: संकेत और सरणियों के बीच अंतर विशाल और पूर्ण हैं! यह है कि आप उनका उपयोग कैसे करते हैं जो हमेशा अलग नहीं होता है। इसके अलावा, संकेत और गतिशील आवंटन वास्तव में रूढ़िवादी अवधारणाएं हैं।
१०:११ पर कक्षा

34
मेरे पालतू जानवरों में से एक @unwind जैसे लोग हैं, जो बीच के व्यर्थ अंतर पर जोर देते हैं sizeof(x)और sizeof x। कोष्ठक संकेतन हमेशा काम करता है और अनिर्दिष्ट संकेतन केवल कभी-कभी काम करता है, इसलिए हमेशा कोष्ठक संकेतन का उपयोग करें; यह याद रखने का एक सरल नियम है और सुरक्षित है। यह एक धार्मिक तर्क में शामिल हो जाता है - मैं उन लोगों के साथ चर्चा में शामिल रहा हूं जो पहले आपत्ति करते हैं - लेकिन 'हमेशा कोष्ठक का उपयोग करें' की सादगी उन्हें (IMNSHO) का उपयोग नहीं करने के लिए किसी भी योग्यता का उपयोग करती है। यह संतुलन के लिए प्रस्तुत किया गया है।
जोनाथन लेफ्लर

24

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


3
न केवल आपको NULL वर्ण के लिए स्थान की अनुमति देना याद रखना चाहिए, आपको NULL वर्ण जोड़ने के लिए याद रखने की आवश्यकता है । strncpy और strncat आपके लिए ऐसा नहीं करते हैं।
ग्रीम पेरो

उह? strncpy () और strncat () निश्चित रूप से समाप्ति वर्ण जोड़ें। वास्तव में, वे बहुत अधिक जोड़ते हैं। कम से कम जब तक बफर में जगह बची है, जो इन कॉल के साथ एक बड़ा जाल है। सिफारिश नहीं की गई।
खोलना

3
@ मेरे विचार से, मुझे लगता है कि ग्रीम की बात यह है कि यदि बफर बहुत छोटा है, तो स्ट्रैन्स्पी या स्ट्रेंकट टर्मिनेटिंग '\ 0' को नहीं जोड़ेगा।
क्विनमार्स

2
snprintf अच्छा है, strncpy / strncat सबसे खराब संभव सिफारिश है, strlcpy / strlcat ज्यादा बेहतर है।
रॉबर्ट गैंबल

9
उपयोग न करें strncpy()। यह नहीं की "सुरक्षित" संस्करण strcpy()। अतिरिक्त '\0'वर्णों के साथ लक्ष्य वर्ण सरणी अनावश्यक रूप से गद्देदार हो सकती है , या इससे भी बदतर हो सकती है, इसे अनारक्षित (यानी, स्ट्रिंग नहीं) छोड़ा जा सकता है। (यह एक डेटा संरचना के साथ उपयोग के लिए डिज़ाइन किया गया था जो अब शायद ही कभी उपयोग किया जाता है, एक चरित्र सरणी को शून्य या अधिक '\0'वर्णों के साथ अंत तक गद्देदार किया जाता है ।)
कीथ थॉम्पसन

22

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

#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 */ 
                ;

15

इसके अलावा अगर आप समय से पहले नहीं जानते हैं कि कितने तार काटे जा रहे हैं, तो मॉलोक और रियललोक उपयोगी हैं।

#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);
}

यह एक अंतहीन लूप में खत्म हो जाएगा जब num_words>INT_MAX, हो सकता है आप का उपयोग करना चाहिए size_tके लिएi
12431234123412341234123

5

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

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

4

जैसा कि लोगों ने बताया कि स्ट्रिंग हैंडलिंग में बहुत सुधार हुआ है। तो आप सीखना चाह सकते हैं कि सी-स्टाइल स्ट्रिंग के बजाय 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;
}

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


<string.h>C ++ शैली है। आप चाहते हैं "string.h"। आप strlen(s1)दो बार गणना भी करते हैं , जिसकी आवश्यकता नहीं है। लंबा s3होना चाहिए totalLenght+1
मूविंग डक

4
@MingDuck: "string.h"बकवास है।
sbi

मैंने थोड़ी देर के लिए सी-स्टाइल स्ट्रिंग्स का उपयोग नहीं किया है। एक निश्चित संस्करण पोस्ट करने के लिए स्वतंत्र महसूस करें।
निल्स

4
@MingDuck: यह गलत है। #include <string.h>सही है। मानक और सिस्टम हेडर (सहित <string.h>) के लिए कोण कोष्ठक का उपयोग करें , हेडर के लिए उद्धरण चिह्न जो आपके कार्यक्रम का हिस्सा हैं। ( #include "string.h"यदि आपके पास उस नाम से अपनी खुद की हेडर फ़ाइल नहीं है, तो भी काम होगा, लेकिन <string.h>फिर भी उपयोग करें ।)
कीथ थॉम्पसन

ध्यान दें कि यह C99- विशिष्ट विशेषताओं पर निर्भर करता है: घोषणाओं और बयानों को मिलाकर, और चर-लंबाई सरणियों (VLAs)। यह भी ध्यान दें कि वीएलएएएस आवंटन विफलताओं का पता लगाने या संभालने के लिए कोई तंत्र प्रदान नहीं करता है; यदि वीएलए को आवंटित करने के लिए पर्याप्त जगह नहीं है, तो आपके कार्यक्रम का व्यवहार अपरिभाषित है।
कीथ थॉम्पसन

4

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

strcat ("Hello, ", name);

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

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

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.

4
यदि var / foo / bar में 1000 से अधिक वर्ण हैं तो क्या होगा? > :)
जियो

1
फिर आपको एक बफर ओवरफ्लो मिलेगा, जिसे आप कोड को पहले से जांचने के लिए जोड़ सकते हैं (जैसे, स्ट्रलेन के साथ)। लेकिन एक कोड स्निपेट का उद्देश्य यह दिखाना है कि कोई चीज़ बिना किसी अतिरिक्त कोड के प्रदूषित किए कैसे काम करती है। अन्यथा मैं लंबाई की जाँच कर रहा हूँ, चाहे var / foo / bar अशक्त था, आदि
paxdiablo

7
@paxdiablo: लेकिन आपने इसका उल्लेख भी नहीं किया, एक सवाल के जवाब में जहां यह उल्लेख करने की आवश्यकता होगी। जो आपके उत्तर को खतरनाक बनाता है । आपने यह भी नहीं बताया कि यह कोड ओपी के मूल कोड से बेहतर क्यों है, इस मिथक को छोड़कर कि यह "आपके मूल के समान परिणाम प्राप्त करता है" (तब क्या बिंदु होगा? मूल टूट गया था !), इसलिए उत्तर अधूरा भी है
ऑर्बिट में

उम्मीद है कि अपनी चिंताओं को संबोधित किया है, @PreferenceBean, हालांकि आदर्श से कम समय पर ढंग से :-) मुझे बताएं कि क्या आपको अभी भी उत्तर के साथ कोई समस्या है, और मैं इसे और सुधारूंगा।
paxdiablo

3

स्ट्रैकट () के पहले तर्क को समतल स्ट्रिंग के लिए पर्याप्त स्थान रखने में सक्षम होना चाहिए। इसलिए परिणाम प्राप्त करने के लिए पर्याप्त जगह के साथ एक बफर आवंटित करें।

char bigEnough[64] = "";

strcat(bigEnough, "TEXT");
strcat(bigEnough, foo);

/* and so on */

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

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


3

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

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

2
आपको लौटना चाहिए char *, नहीं const char *। वापसी मान को पारित करने की आवश्यकता होगी free
प्रति जोहानसन

दुर्भाग्य asprintfसे केवल एक GNU एक्सटेंशन है।
कैलमेरियस

3

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

अब यह काफी असुविधाजनक है क्योंकि आपको किसी चीज़ को जोड़ने के लिए अंतिम चरित्र को खोजना होगा। strcatआपके लिए वही करेंगे।

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

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

message = strcat("TEXT " + var);

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

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

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

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

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

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

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

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

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


का प्रकार "TEXT"है char[5], नहीं const char* । यह char*ज्यादातर संदर्भों में तय करता है। पिछड़े संगतता कारणों के लिए, स्ट्रिंग शाब्दिक नहीं हैं const, लेकिन उन्हें संशोधित करने का प्रयास अपरिभाषित व्यवहार में परिणाम देता है। (C ++ में, स्ट्रिंग शाब्दिक हैं const।)
कीथ थॉम्पसन

2

आप अपना स्वयं का फ़ंक्शन लिख सकते हैं जो समान कार्य करता है 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अपनी आवश्यकताओं के अनुरूप मूल्य बदल सकते हैं।


मैं बफर अतिप्रवाह की उम्मीद करता हूं, मैं आपको आवंटित देखता हूं strlen(str1) + strlen(str2), लेकिन आप strlen(str1) + strlen(str2) + 1वर्ण लिखते हैं। तो क्या आप वास्तव में अपना कार्य लिख सकते हैं?
Liviu

वाह! तुम कभी भी स्मृति को मुक्त नहीं करते हो, गंदा, गंदा! return buffer; free(buffer);
Liviu

BTW, sizeof(char) == 1(इसके अलावा, अन्य सूक्ष्म त्रुटियां हैं ...) क्या आप देख सकते हैं कि अब आपको अपना फ़ंक्शन क्यों नहीं लिखना है?
Liviu

@ लिविउ मैं स्मृति को लाइन में फ्री करता हूं free(buffer);
डोनाल्ड डक

1
free(buffer);बाद return buffer;में कभी नहीं निष्पादित किया जाता है, इसे डिबगर में देखें;) अब मैं देखता हूं: हां, आपको mainफ़ंक्शन में मेमोरी को मुक्त करना होगा
Liviu

1

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

#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, यदि आप पहले से ही अपने प्रोग्राम में कहीं भी प्रिंटफ का उपयोग कर रहे हैं, तो स्निपरफ () का उपयोग करने का कोई कारण नहीं है, क्योंकि संकलित कोड बड़ा होगा (लेकिन इनबिल्ट और काफी तेज)

1
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;
}

1

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

विशेष रूप से:

... स्निप ...

गंतव्य

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

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


0

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

#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");

0

कुछ इसी तरह की कोशिश करो:

#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;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.