String concatenation without strcat in C

前端 未结 7 759
伪装坚强ぢ
伪装坚强ぢ 2021-01-13 13:44

I am having trouble concatenating strings in C, without strcat library function. Here is my code

#include
#include
#include<         


        
相关标签:
7条回答
  • 2021-01-13 14:26

    You cannot safely write into those arrays, since you have not made sure that enough space is available. If you use malloc() to allocate space, you can't then overwrite the pointer by assigning to string literal. You need to use strcpy() to copy a string into the newly allocated buffers, in that case.

    Also, the length of a string in C is computed by the strlen() function, not length() that you're using.

    When concatenating, you need to terminate at the proper location, which your code doesn't seem to be doing.

    Here's how I would re-implement strcat(), if needed for some reason:

    char * my_strcat(char *out, const char *in)
    {
      char *anchor = out;
      size_t olen;
    
      if(out == NULL || in == NULL)
        return NULL;
    
      olen = strlen(out);
      out += olen;
      while(*out++ = *in++)
        ;
      return anchor;
    }
    

    Note that this is just as bad as strcat() when it comes to buffer overruns, since it doesn't support limiting the space used in the output, it just assumes that there is enough space available.

    0 讨论(0)
  • 2021-01-13 14:36

    Old answer below


    You can initialize a string with strcpy, like in your code, or directly when declaring the char array.

    char a1[100] = "Vivek";
    

    Other than that, you can do it char-by-char

    a1[0] = 'V';
    a1[1] = 'i';
    // ...
    a1[4] = 'k';
    a1[5] = '\0';
    

    Or you can write a few lines of code that replace strcpy and make them a function or use directly in your main function.


    Old answer

    You have

            0 1 2 3 4 5 6 7 8 9 ...
        a1 [V|i|v|e|k|0|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_]
        b1 [R|a|t|n|a|v|e|l|0|_|_|_|_|_|_|_|_|_|_|_|_|_]
    

    and you want

            0 1 2 3 4 5 6 7 8 9 ...
        a1 [V|i|v|e|k|R|a|t|n|a|v|e|l|0|_|_|_|_|_|_|_|_]
    

    so ...

    a1[5] = 'R';
    a1[6] = 'a';
    // ...
    a1[12] = 'l';
    a1[13] = '\0';
    

    but with loops and stuff, right? :D

    Try this (remember to add missing bits)

    for (aindex = 5; aindex < 14; aindex++) {
        a1[aindex] = b1[aindex - 5];
    }
    

    Now think about the 5 and 14 in the loop above.

    What can you replace them with? When you answer this, you have solved the programming problem you have :)

    0 讨论(0)
  • 2021-01-13 14:40

    It is better to factor out your strcat logic to a separate function. If you make use of pointer arithmetic, you don't need the strlen function:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h> /* To completely get rid of this, 
                           implement your our strcpy as well */
    
    static void 
    my_strcat (char* dest, char* src)
    {
      while (*dest) ++dest;
      while (*src) *(dest++) = *(src++);
      *dest = 0;
    }
    
    int 
    main()
    {
      char* a1 = malloc(100);
      char* b1 = malloc(100);
    
      strcpy (a1, "Vivek");  
      strcpy (b1, " Ratnavel");
    
      my_strcat (a1, b1);
      printf ("%s\n", a1); /* => Vivek Ratnavel */
    
      free (a1);
      free (b1);
      return 0;
    }
    
    0 讨论(0)
  • 2021-01-13 14:41

    Problems:

    1. length isn't a function. strlen is, but you probably shouldn't call it in a loop - b1's length won't change on us, will it? Also, it returns a size_t, which may be the same size as int on your platform but will be unsigned. This can (but usually won't) cause errors, but you should do it right anyway.
    2. a1 only has enough space for the first string, because the compiler doesn't know to allocate extra stack space for the rest of the string since. If you provide an explicit size, like [100], that should be enough for your purposes. If you need robust code that doesn't make assumptions about what is "enough", you should look into malloc and friends, though that may be a lesson for another day.
    3. Your loop stops too early. i < b1_len (assuming you have a variable, b1_len, that was set to the length of b1 before the loop began) would be sufficient - strlen doesn't count the '\0' at the end.
    4. But speaking of counting the '\0' at the end, a slightly more efficient implementation could use sizeof a1 - 1 instead of strlen(a1) in this case, since a1 (and b1) are declared as arrays, not pointers. It's your choice, but remember that sizeof won't work for pointers, so don't get them mixed up.
      EDIT: New problems:
    5. char *p = malloc(/*some*/); p = /* something */ is a problem. = with pointers doesn't copy contents, it copies the value, so you're throwing away the old pointer value you got from malloc. To copy the contents of a string into a char * (or a char [] for that matter) you'd need to use strcpy, strncpy, or (my preference) memcpy. (Or just a loop, but that's rather silly. Then again, it may be good practice if you're writing your own strcat.)
    6. Unless you're using C++, I wouldn't cast the return value of malloc, but that's a religious war and we don't need one of those.
    7. If you have strdup, use it. If you don't, here is a working implementation:

      char *strdup(const char *c)
      {
          size_t l = strlen(c);
          char *d = malloc(l + 1);
          if(d) memcpy(d, c, l + 1);
          return d;
      }
      

      It is one of the most useful functions not in the C standard library.

    0 讨论(0)
  • 2021-01-13 14:43
     char a1[] = "Vivek";
    

    Will create a char array a1 of size 6. You are trying to stuff it with more characters than it can hold.

    If you want to be able to accommodate concatenation "Vivek" and "Ratnavel" you need to have a char array of size atleast 14 (5 + 8 + 1).

    In your modified program you are doing:

    char *a1=(char*)malloc(100);  // 1
    a1 = "Vivek";                 // 2
    

    1: Will allocate a memory chunk of size 100 bytes, makes a1 point to it.
    2: Will make a1 point to the string literal "Vivek". This string literal cannot be modified.

    To fix this use strcpy to copy the string into the allocated memory:

    char *a1=(char*)malloc(100);  
    strcpy(a1,"Vivek");
    

    Also the for loop condition i<strlen(b1)-1 will not copy last character from the string, change it to i<strlen(b1)

    And

    a1[i]='\0';
    

    should be

    a1[i + len]='\0';
    

    as the new length of a1 is i+len and you need to have the NUL character at that index.

    And don't forget to free your dynamically allocated memory once you are done using it.

    0 讨论(0)
  • 2021-01-13 14:43

    You can do it using strcpy() too ;)

    char *a = (char *) malloc(100);
    char *b = (char *) malloc(100);
    
    strcpy(a, "abc");               // initializes a
    strcpy(b, "def");               // and b
    
    strcpy((a + strlen(a)), b);     // copy b at end of a
    
    printf("%s\n",a);               // will produce: "abcdef"
    
    0 讨论(0)
提交回复
热议问题