const char * संघात


116

मुझे इस तरह से दो कांस्टेन्स को सम्‍मिलित करने की आवश्‍यकता है:

const char *one = "Hello ";
const char *two = "World";

मैं ऐसा करने के बारे में कैसे जा सकता हूं?

मैं char*एक सी इंटरफ़ेस के साथ एक तृतीय-पक्ष पुस्तकालय से इन s पारित कर रहा हूँ ताकि मैं बस के std::stringबजाय का उपयोग नहीं कर सकते ।


6
मैं उलझन में हूँ - मूल प्रश्नकर्ता ने "c ++" टैग लिखा - फिर किसी और ने इसे हटा दिया। इस प्रश्न के लिए मामलों की स्थिति क्या है? क्या C ++ कोड की अनुमति है?
जोहान्स शाउब -

1
@ जोहान्स: यह एक बेहतर प्रश्न xD है।
प्रसून सौरव

यह भी ध्यान दें कि मूल प्रश्न C का संदर्भ नहीं था - मैंने वह टैग हटा दिया है।

मैंने C ++ टैग को C पर स्विच कर दिया क्योंकि OP ने एक उत्तर स्वीकार किया जो स्टैक strcpyऔर strcatकॉल पर सरणियों का उपयोग करता है , मैंने सोचा कि टैग को बदलने के लिए समझ में आया।
ग्रेगरी पकोसज

7
C और C ++ टैग जोड़े गए । जैसा कि ओपी एक टिप्पणी में बताते हैं, वह C ++ कोड लिख रहा है, लेकिन एक लाइब्रेरी को कॉल करता है जो C इंटरफ़ेस का उपयोग करता है। प्रश्न दोनों भाषाओं में प्रासंगिक है।
जालफ

जवाबों:


110

आपके उदाहरण में एक और दो चार बिंदु हैं, चार स्थिरांक की ओर इशारा करते हैं। आप इन बिंदुओं द्वारा बताए गए चार स्थिरांक नहीं बदल सकते हैं। तो ऐसा कुछ भी:

strcat(one,two); // append string two to string one.

काम नहीं करेगा। इसके बजाय आपको परिणाम धारण करने के लिए एक अलग चर (चार सरणी) होना चाहिए। कुछ इस तरह:

char result[100];   // array to hold the result.

strcpy(result,one); // copy string one into the result.
strcat(result,two); // append string two to the result.

7
चार * परिणाम के बारे में क्या; result = calloc (strlen (एक) + strlen (दो) +1, sizeof (char)); और क्या strcpy + strcat?
लुसीबुबल

3
@luiscubal: हाँ, यह भी काम करेगा ... बस एक (चार *) कास्ट का उपयोग करें, जैसा कि कॉलोक रिटर्न शून्य *
कोडादिक

5
इस उत्तर के साथ समस्या हार्ड कोडित सरणी आकार है। यह वास्तव में बुरी आदत है, खासकर अगर आपको नहीं पता कि "एक" और "दो" क्या हैं।
पॉल टॉम्बलिन

1
पहले उदाहरण में, ऐसा strcpy(one,two);होना चाहिए strcat(one,two);(ऐसा नहीं है जो इसे सही बनाता है, जैसा कि आप सही ढंग से इंगित करते हैं)।
आलोक सिंघल

1
sprintf(dest,"%s%s",one,two)कॉपी के बारे में क्या और भूल गए?
मप्र

81

सी तरीका:

char buf[100];
strcpy(buf, one);
strcat(buf, two);

सी ++ तरीका:

std::string buf(one);
buf.append(two);

संकलन-समय तरीका:

#define one "hello "
#define two "world"
#define concat(first, second) first second

const char* buf = concat(one, two);

31

यदि आप C ++ का उपयोग कर रहे हैं, तो आप std::stringC- स्टाइल स्ट्रिंग्स के बजाय उपयोग क्यों नहीं करते ?

std::string one="Hello";
std::string two="World";

std::string three= one+two;

यदि आपको इस स्ट्रिंग को सी-फ़ंक्शन में पास करने की आवश्यकता है, तो बस पास करें three.c_str()


7
क्योंकि मैं एक पुस्तकालय का उपयोग कर रहा हूं जिसे C में कोडित किया गया था इसलिए फ़ंक्शंस const const चार *
एंथोनी कैलडवेल

1
@AnthoniCaldwell: हंसी के लिए धन्यवाद। मैं काम के दबाव के कारण नहीं कर पाया ।
D

एक नए काम के लिए अपने समय की तरह लगता है? ...
मैक्स


17
const char *one = "Hello ";
const char *two = "World";

string total( string(one) + two );

// to use the concatenation as const char*, use:
total.c_str()

अपडेट किया गया: प्रदर्शन कारणों string total = string(one) + string(two); से परिवर्तित किया गया string total( string(one) + two );(स्ट्रिंग दो और अस्थायी स्ट्रिंग कुल के निर्माण से बचा जाता है)

// string total(move(move(string(one)) + two));  // even faster?

@iburidu क्या आपने इसे मापा है? उन स्थितियों के बारे में जहां सुरक्षा ट्रम्प प्रदर्शन करते हैं? (वे आम स्थितियाँ हैं)
सकी १15

3
@ सकी पूरी तरह से ऐसी कोई भी स्थिति नहीं है जहां यह किसी अन्य समाधान की तुलना में अधिक सुरक्षित है, लेकिन यह एक संकलित समय समाधान की तुलना में हमेशा धीमी है, रनटाइम व्यवहार को लागू करने के साथ-साथ लगभग निश्चित रूप से स्मृति आवंटन को भी रोकती है।
ऐलिस

8

एक और उदाहरण:

// calculate the required buffer size (also accounting for the null terminator):
int bufferSize = strlen(one) + strlen(two) + 1;

// allocate enough memory for the concatenated string:
char* concatString = new char[ bufferSize ];

// copy strings one and two over to the new buffer:
strcpy( concatString, one );
strcat( concatString, two );

...

// delete buffer:
delete[] concatString;

लेकिन जब तक आप विशेष रूप से C ++ मानक पुस्तकालय का उपयोग नहीं कर सकते या नहीं कर सकते, तब तक उपयोग std::stringकरना शायद सुरक्षित है।


1
यदि OP C ++ का उपयोग नहीं कर सकता है, तो वह उपयोग नहीं कर सकता है new। और अगर वह इसका उपयोग कर सकता है, तो उसे उपयोग करना चाहिए std::string, जैसा कि आप कहते हैं।
आलोक सिंघल

5

ऐसा लगता है कि आप C ++ का उपयोग C लाइब्रेरी के साथ कर रहे हैं और इसलिए आपको साथ काम करने की आवश्यकता है const char *

मेरा सुझाव है कि उन const char *में लपेटकर std::string:

const char *a = "hello "; 
const char *b = "world"; 
std::string c = a; 
std::string d = b; 
cout << c + d;

5

सबसे पहले, आपको कुछ डायनामिक मेमोरी स्पेस बनाना होगा। तब आप इसमें दो तार डाल सकते हैं। या आप सी ++ "स्ट्रिंग" वर्ग का उपयोग कर सकते हैं। पुराने स्कूल का रास्ता:

  char* catString = malloc(strlen(one)+strlen(two)+1);
  strcpy(catString, one);
  strcat(catString, two);
  // use the string then delete it when you're done.
  free(catString);

नया C ++ तरीका

  std::string three(one);
  three += two;

आपको गतिशील मेमोरी की आवश्यकता क्यों है?
लुका मैटिस

4
-1 मेरे लिए, पहले सी-वे के साथ आपको मॉलोक और मुफ्त का उपयोग करने की आवश्यकता है। फिर भी अगर आप नया करते हैं तो इसे हटा दिया जाना चाहिए [और नहीं]।
नवीन

मेरे द्वारा उपयोग की जा रही लाइब्रेरी को C नहीं C ++ में कोडित किया गया है ताकि सभी फ़ंक्शंस कॉन्स्टर्ड चार * नॉट स्ट्रिंग लौटें।
एंथोनी कैलडवेल

1
@ नवीन, टैग ने कहा "C ++"। यदि आप नए का उपयोग नहीं कर सकते हैं और हटा सकते हैं, तो उसे C ++ टैग का उपयोग नहीं करना चाहिए।
पॉल टॉम्बलिन

5

यदि आप तार के आकार को नहीं जानते हैं, तो आप कुछ इस तरह से कर सकते हैं:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
    const char* q1 = "First String";
    const char* q2 = " Second String";

    char * qq = (char*) malloc((strlen(q1)+ strlen(q2))*sizeof(char));
    strcpy(qq,q1);
    strcat(qq,q2);

    printf("%s\n",qq);

    return 0;
}

3

आप उपयोग कर सकते हैं strstream। यह औपचारिक रूप से पदावनत है, लेकिन यह अभी भी एक महान उपकरण है यदि आपको सी स्ट्रिंग्स के साथ काम करने की आवश्यकता है, तो मुझे लगता है।

char result[100]; // max size 100
std::ostrstream s(result, sizeof result - 1);

s << one << two << std::ends;
result[99] = '\0';

यह लिखेगा oneऔर फिर twoस्ट्रीम में, और एक टर्मिनेटिंग एपेंड \0का उपयोग करेगा std::ends। मामले में दोनों तार ठीक 99अक्षर लिख सकते हैं - इसलिए कोई स्थान लिखना नहीं छोड़ा जाएगा \0- हम अंतिम स्थिति में मैन्युअल रूप से लिखते हैं।


पदावनति बहुत अधिक मायने नहीं रखती है। भले ही यह मानक के भविष्य के संस्करण से हटा दिया गया हो, यह आपके अपने नामस्थान में फिर से लागू करने के लिए इतना काम नहीं है।
स्टीव जेसप

@Steve, वास्तव में :) और अपने स्वयं के streambufनिर्देशन आउटपुट को एक बफ़र के लिए उपयोग किया जाता है जिसके साथ ostreamया तो बहुत मुश्किल नहीं है।
जोहान्स शाउब -


0

मेमोरी के गतिशील आवंटन में strcpy कमांड का उपयोग किए बिना दो निरंतर चार पॉइंटर को जोड़ना:

const char* one = "Hello ";
const char* two = "World!";

char* three = new char[strlen(one) + strlen(two) + 1] {'\0'};

strcat_s(three, strlen(one) + 1, one);
strcat_s(three, strlen(one) + strlen(two) + 1, two);

cout << three << endl;

delete[] three;
three = nullptr;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.