简体   繁体   中英

concatenate two strings without strcat

I want to concatenate two strings without using strcat() function.But I am not getting the required result. Please point me my mistake.

void main() {
    char s1[100], s2[100];
    int i;

    puts("First string?");
    gets(s1);

    puts("Second string?");
    gets(s2);

    for (i = strlen(s1); i <= (strlen(s1) + strlen(s2)); i++) {
        s1[i] = s2[i - strlen(s1)];
    }

    puts(s1);
}

I didn't really change much in your program, but here's what I have (modified from yours) and it works.

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

int main(void)
  {
    char s1[100], s2[100];
    size_t i, s1l, s2l, total;

    puts("First string?");
    fgets(s1, sizeof(s1), stdin);
    s1[strlen(s1) - 1] = 0x00;

    puts("Second string?");
    fgets(s2, sizeof(s2), stdin);
    s2[strlen(s2) - 1] = 0x00;

    s1l = strlen(s1);
    s2l = strlen(s2);
    total = s1l + s2l;

    for(i = s1l; i <= total; i++)
      {
        s1[i] = s2[i - s1l];
      }

    puts(s1);

    return(0);
  }

Using your program verbatim, the problem was that since the length of s1 was changing at each iteration of the loop, the strlen(s1) in the check kept increasing in value so you would basically end up with a mostly infinite loop...at least until it encountered some random null byte. However, when taking the length of the strings before hand, the loop terminus count does not change which results in the proper output. My code will compile and run correctly on a FreeBSD 10.2 system using the clang compiler.

As a side note, DO NOT return void on main. ALWAYS return int. Also specify the library headers that you plan to use.

EDIT: I modified the code to use fgets instead of gets since gets is completely unsafe. It does not check buffer sizes so you can easily have a buffer overflow.

Use a variation of sprintf:

simpler

char buf[200];
sprintf(buf, "%s%s" s1, s2);

simpler and safer

char buf[200]
snprintf(buf, sizeof(buf), "%s%s", s1, s2);//prevents buffer overflow

Or, modify your loop (see in line comments for why):

int main(void)//note changed main prototype
{
        char s1[100], s2[100];//caution here: s1 must be big enough
                              //to contain its string as well as
                              //the string stored in s2, plus 1 for NULL
        int i;
        int len1, len2;//create variables to store string lengths

        puts("First string?");
        gets(s1);//note, gets is no longer recommended

        puts("Second string?");
        gets(s2);
        len1 = strlen(s1);//store string lengths only once
        len2 = strlen(s2);//to avoid calling them repeatedly in loop

        for(i = 0; i < len2; i++)//index i in one place only
        {
            s1[len1+i] = s2[i];
        }
        s1[len1 + i]=0;//null terminate string when done.
        puts(s1);
        getchar();//added to pause execution in my environment.
        return 0;
}

A sample session using the above modifications is shown here: 在此处输入图片说明

The length of s1 is getting changed at runtime, making your index i incorrect. Try something like below:-

l = strlen(s1);

for(i = 0; i < strlen(s2); i++)
{
   s1[l++] = s2[i];
}

s1[l] = '\0';

Suppose s1 = "hello" and s2 = "world", then in the first iteration length of s1 = 5 and index for s2 = 0(i- length(s1)); works well. But in the second iteration length(s1) = 6 and index for s2 = 0(i-length(s1)). so index for taking the character from s2 is not changing. This was about the problem in your implementation, though you should an efficient way by using sprintf.

sprintf(s1, "%s%s", s1, s2);

Your solution does not work because you recompute strlen(s1) upon each iteration to test for completion and to figure the offset in s2 to copy a character from, but you modify s1 in the loop, so the length changes, and even worse, s1 is temporarily no longer '\\0' terminated: the test expression i <= strlen(s1) + strlen(s2) invokes undefined behavior, and the same happens when you copy s2[i - strlen(s1)] the second time through the loop.

Use these ideas to correct your code:

  • do not use gets to read input, use fgets() and remove the final '\\n' .

  • compute the length of s1 and s2 only once and store them in local variables.

  • verify that the concatenation will not exceed the size of s1 .

  • rewrite your loop with these local variables, or use strcpy or memcpy .

Here is an example:

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

int main(void) {
    char s1[100], s2[100];
    size_t i, len1, len2;

    puts("First string?");
    if (!fgets(s1, sizeof s1, stdin))
        return 1;

    len1 = strlen(s1);
    if (len1 > 0 && s1[len1 - 1] == '\n')
        s1[--len1] = '\0';

    puts("Second string?");
    if (!fgets(s2, sizeof s2, stdin))
        return 1;

    len2 = strlen(s2);
    if (len2 > 0 && s2[len2 - 1] == '\n')
        s1[--len2] = '\0';

    if (len1 + len2 >= sizeof s1)
        return 2;

    /* copy the characters from s2 including the final '\0' */
    for (i = 0; i <= len2; i++) {
        s1[len1 + i] = s2[i];
    }

    puts(s1);

    return 0;
}
// A simple strcat function

int main(void)
{
    char str1[100] ="Avis";
    stringcat(str1,"karthik");
    printf("\n%s",str1);
    return 0;
}
void stringcat(char *str1, char *str2)
{
   while(*str1)
       str1++;
   while(*str2)
       *str1++ = *str2++;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM