मैं सी में दो तार कैसे मिलाऊंगा?


141

मैं दो तार कैसे जोड़ूं?

मैंने कोशिश की name = "derp" + "herp";, लेकिन मुझे एक त्रुटि मिली:

अभिव्यक्ति में अभिन्न या enum प्रकार होना चाहिए

जवाबों:


184

C के पास उन स्ट्रिंग्स के लिए समर्थन नहीं है जो कुछ अन्य भाषाओं में हैं। सी में एक स्ट्रिंग सिर्फ एक सरणी के लिए एक संकेतक charहै जिसे पहले अशक्त चरित्र द्वारा समाप्त किया जाता है। सी में कोई स्ट्रिंग संघटन ऑपरेटर नहीं है।

strcatदो तारों को समतल करने के लिए उपयोग करें । आप इसे करने के लिए निम्नलिखित फ़ंक्शन का उपयोग कर सकते हैं:

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

char* concat(const char *s1, const char *s2)
{
    char *result = malloc(strlen(s1) + strlen(s2) + 1); // +1 for the null-terminator
    // in real code you would check for errors in malloc here
    strcpy(result, s1);
    strcat(result, s2);
    return result;
}

यह ऐसा करने का सबसे तेज़ तरीका नहीं है, लेकिन आपको इस बारे में चिंता नहीं करनी चाहिए। ध्यान दें कि फ़ंक्शन कॉल करने वाले को आवंटित स्मृति के ढेर को वापस करता है और उस मेमोरी के स्वामित्व पर गुजरता है। यह freeस्मृति के लिए कॉल करने वाले की जिम्मेदारी है जब इसकी आवश्यकता नहीं होती है।

फ़ंक्शन को इस तरह से कॉल करें:

char* s = concat("derp", "herp");
// do things with s
free(s); // deallocate the string

यदि आपने प्रदर्शन से परेशान होने के लिए किया था, तो आप बार-बार शून्य-टर्मिनेटर की तलाश में इनपुट बफ़र्स को स्कैन करने से बचना चाहेंगे।

char* concat(const char *s1, const char *s2)
{
    const size_t len1 = strlen(s1);
    const size_t len2 = strlen(s2);
    char *result = malloc(len1 + len2 + 1); // +1 for the null-terminator
    // in real code you would check for errors in malloc here
    memcpy(result, s1, len1);
    memcpy(result + len1, s2, len2 + 1); // +1 to copy the null-terminator
    return result;
}

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


1
छोटा सा: कोड स्ट्रिंग के पहले भाग की प्रतिलिपि पिछले और उसके बाद कर सकता है return memcpy(result, s1, len1);। यद्यपि एक माइक्रो-ऑप्टिमाइज़ेशन या कम से कम कोड गोल्फिंग, बुनियादी स्ट्रिंग ऑपरेशनों पर इस तरह के संभावित सुधारों का मूल्य उनके उच्च उपयोग को दे सकता है।
chux -

2
पहले संस्करण का छोटा प्रदर्शन सुधार stpcpy, जो पहले स्ट्रिंग के अंत में एक पॉइंटर लौटाता है:strcpy(stpcpy(result, s1), s2);
डैनियल

17
#include <stdio.h>

int main(){
    char name[] =  "derp" "herp";
    printf("\"%s\"\n", name);//"derpherp"
    return 0;
}

1
यह सी में मैक्रोज़ के लिए भी काम करता है, जो ध्यान देने योग्य है
अबे फेहर

15

डेविड हेफर्नन ने अपने जवाब में इस मुद्दे को समझाया , और मैंने बेहतर कोड लिखा। निचे देखो।

एक सामान्य कार्य

हम किसी भी संख्या में तार को समाप्‍त करने के लिए एक उपयोगी परिवर्तन कार्य लिख सकते हैं:

#include <stdlib.h>       // calloc
#include <stdarg.h>       // va_*
#include <string.h>       // strlen, strcpy

char* concat(int count, ...)
{
    va_list ap;
    int i;

    // Find required length to store merged string
    int len = 1; // room for NULL
    va_start(ap, count);
    for(i=0 ; i<count ; i++)
        len += strlen(va_arg(ap, char*));
    va_end(ap);

    // Allocate memory to concat strings
    char *merged = calloc(sizeof(char),len);
    int null_pos = 0;

    // Actually concatenate strings
    va_start(ap, count);
    for(i=0 ; i<count ; i++)
    {
        char *s = va_arg(ap, char*);
        strcpy(merged+null_pos, s);
        null_pos += strlen(s);
    }
    va_end(ap);

    return merged;
}

प्रयोग

#include <stdio.h>        // printf

void println(char *line)
{
    printf("%s\n", line);
}

int main(int argc, char* argv[])
{
    char *str;

    str = concat(0);             println(str); free(str);
    str = concat(1,"a");         println(str); free(str);
    str = concat(2,"a","b");     println(str); free(str);
    str = concat(3,"a","b","c"); println(str); free(str);

    return 0;
}

आउटपुट:

  // Empty line
a
ab
abc

साफ - सफाई

ध्यान दें कि जब आप स्मृति लीक से बचने के लिए अनावश्यक हो जाते हैं, तो आपको आवंटित मेमोरी को मुक्त करना चाहिए:

char *str = concat(2,"a","b");
println(str);
free(str);

3
कॉलोक के तर्क पिछड़े हैं। उन्हें तब आकार में गिना जाना चाहिए। आप इसे इसके साथ दूर ले जाते हैं, गुणक पहचान के लिए धन्यवाद, क्योंकि sizeof (चार) को परिभाषित किया गया है 1.
एंडी

विचार करें int len-> size_t lenजैसा size_tकि "आकार" कोड के लिए सही प्रकार है। इसके अलावा // room for NULL-> // room for null character NULLअशक्त सूचक का अर्थ है।
chux -

9

मुझे लगता है कि आप इसे एक बंद चीजों के लिए की आवश्यकता होगी। मुझे लगता है कि आप एक पीसी डेवलपर हैं।

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

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

#define STR_SIZE 10000

int main()
{
  char s1[] = "oppa";
  char s2[] = "gangnam";
  char s3[] = "style";

  {
    char result[STR_SIZE] = {0};
    snprintf(result, sizeof(result), "%s %s %s", s1, s2, s3);
    printf("%s\n", result);
  }
}

यदि 10 केबी प्रति स्ट्रिंग पर्याप्त नहीं होगा, तो आकार में एक शून्य जोड़ें और परेशान न करें, - वे वैसे भी स्कोप के अंत में अपनी स्टैक मेमोरी जारी करेंगे।


1
इसे अधिक स्पष्ट रूप से व्यक्त किया जाएगाsnprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
एमएम

8

आप का उपयोग करना चाहिए strcat, या बेहतर, strncat। Google इसे (कीवर्ड "कॉन्सेटैनेटिंग" है)।


8
खबरदार: strncat()सही ढंग से उपयोग करने के लिए एक कठिन कठिन कार्य है। जल्दी से, मैनुअल को देखे बिना, आप किस लंबाई को निर्दिष्ट करते हैं strncat()? यदि आपने "बफर की लंबाई" कहा है, तो आपने बस मेरी बात को अच्छी तरह से प्रदर्शित किया है। इसका एक काउंटर-सहज ज्ञान युक्त इंटरफ़ेस है और जब आपके पास इसे सुरक्षित रूप से उपयोग करने के लिए पर्याप्त डेटा है, तो आपको पहले स्थान पर फ़ंक्शन का उपयोग करने की आवश्यकता नहीं है - अन्य, तेज और अधिक कुशल विकल्प (जैसे कि strcpy()या memmove()) हैं जिनका उपयोग किया जा सकता है बजाय। बहुत ज्यादा जो भी 'मुझे क्या उपयोग करना चाहिए' का सवाल है, strncat()जवाब नहीं है।
जोनाथन लेफ्लर 3

5

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


3

GNU एक्सटेंशन के बिना:

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

int main(void) {
    const char str1[] = "First";
    const char str2[] = "Second";
    char *res;

    res = malloc(strlen(str1) + strlen(str2) + 1);
    if (!res) {
        fprintf(stderr, "malloc() failed: insufficient memory!\n");
        return EXIT_FAILURE;
    }

    strcpy(res, str1);
    strcat(res, str2);

    printf("Result: '%s'\n", res);
    free(res);
    return EXIT_SUCCESS;
}

वैकल्पिक रूप से GNU एक्सटेंशन के साथ:

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

int main(void) {
    const char str1[] = "First";
    const char str2[] = "Second";
    char *res;

    if (-1 == asprintf(&res, "%s%s", str1, str2)) {
        fprintf(stderr, "asprintf() failed: insufficient memory!\n");
        return EXIT_FAILURE;
    }

    printf("Result: '%s'\n", res);
    free(res);
    return EXIT_SUCCESS;
}

देखें malloc , मुक्त और asprintf अधिक जानकारी के लिए।


2
#include <string.h>
#include <stdio.h>
int main()
{
   int a,l;
   char str[50],str1[50],str3[100];
   printf("\nEnter a string: ");
   scanf("%s",str);
   str3[0]='\0';
   printf("\nEnter the string which you want to concat with string one: ");
   scanf("%s",str1);
   strcat(str3,str);
   strcat(str3,str1);
   printf("\nThe string is %s\n",str3);
}

2

कॉनटैनेट स्ट्रिंग्स

सी में किसी भी दो तारों को समेटते हुए कम से कम 3 तरीके से किया जा सकता है: -

1) स्ट्रिंग 2 के अंत तक स्ट्रिंग 2 की प्रतिलिपि बनाकर

#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
  char str1[MAX],str2[MAX];
  int i,j=0;
  printf("Input string 1: ");
  gets(str1);
  printf("\nInput string 2: ");
  gets(str2);
  for(i=strlen(str1);str2[j]!='\0';i++)  //Copying string 2 to the end of string 1
  {
     str1[i]=str2[j];
     j++;
  }
  str1[i]='\0';
  printf("\nConcatenated string: ");
  puts(str1);
  return 0;
}

2) स्ट्रिंग 1 और स्ट्रिंग 2 से स्ट्रिंग 3 की प्रतिलिपि बनाकर

#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
  char str1[MAX],str2[MAX],str3[MAX];
  int i,j=0,count=0;
  printf("Input string 1: ");
  gets(str1);
  printf("\nInput string 2: ");
  gets(str2);
  for(i=0;str1[i]!='\0';i++)          //Copying string 1 to string 3
  {
    str3[i]=str1[i];
    count++;
  }
  for(i=count;str2[j]!='\0';i++)     //Copying string 2 to the end of string 3
  {
    str3[i]=str2[j];
    j++;
  }
  str3[i]='\0';
  printf("\nConcatenated string : ");
  puts(str3);
  return 0;
}

3) strcat () फ़ंक्शन का उपयोग करके

#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
  char str1[MAX],str2[MAX];
  printf("Input string 1: ");
  gets(str1);
  printf("\nInput string 2: ");
  gets(str2);
  strcat(str1,str2);                    //strcat() function
  printf("\nConcatenated string : ");
  puts(str1);
  return 0;
}

0

सी में, आपके पास वास्तव में तार नहीं हैं, एक सामान्य प्रथम श्रेणी की वस्तु के रूप में। आपको उन्हें वर्णों के सरणियों के रूप में प्रबंधित करना होगा, जिसका अर्थ है कि आपको यह निर्धारित करना होगा कि आप अपने सरणियों का प्रबंधन कैसे करना चाहते हैं। एक तरह से सामान्य चर है, जैसे स्टैक पर रखा गया है। एक अन्य तरीका उन्हें गतिशील रूप से उपयोग करके आवंटित करना है malloc

आपके द्वारा छांटे जाने के बाद, आप दो स्ट्रिंग का उपयोग करके strcpyया करने के लिए एक सरणी की सामग्री को दूसरे में कॉपी कर सकते हैं strcat

कहा जाता है कि, C में "स्ट्रिंग शाब्दिक" की अवधारणा है, जो संकलित समय में ज्ञात तार हैं। जब उपयोग किया जाता है, तो वे रीड-ओनली मेमोरी में रखा गया एक कैरेक्टर एरे होगा। हालाँकि, दो स्ट्रिंग शाब्दिकों को एक-दूसरे के बगल में लिखकर उन्हें सम्‍मिलित करना संभव है, जैसा "foo" "bar"कि स्ट्रिंग शाब्दिक "फोब्बर" का निर्माण करेगा।


0

मेमकी का उपयोग करना

char *str1="hello";
char *str2=" world";
char *str3;

str3=(char *) malloc (11 *sizeof(char));
memcpy(str3,str1,5);
memcpy(str3+strlen(str1),str2,6);

printf("%s + %s = %s",str1,str2,str3);
free(str3);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.