asdfasdasdfaasdf
asdfasdasdfaasdf

Reputation: 13

Problem with a function similar to strcat()

I tried to write a function similar to strcat() in c++. Here is the code of this function:

char *mystrcat(char *str1, char *str2){
    int i = 0;
    char *buffer = str1;
    while(*str1){
        str1++; i++;
    }
    i++;
    while(*str2){
        str1[i] = *str2;
        str2++; i++;
    }
    str1[++i] = '\0';
    str1 = buffer;
    return str1;
}

The input values for this function are given by this code:

char string1[100], string2[100];
    cout << "Enter string 1 ";
    cin >> string1;
    cout << "Enter string 2 ";
    cin >> string2;
    mystrcat(string1, string2);
    cout << string1 << endl;

When I ran the code and tried to input two strings, it has given me this output:

Enter string 1 qwerty
Enter string 2 asdf
qwerty

Why the first string is displayed only?

Upvotes: 1

Views: 89

Answers (2)

paxdiablo
paxdiablo

Reputation: 881553

For a start, since you're incrementing both str1 and i in the first loop, you're going to move twice as fast through that array as you think. Thats because you're increasing both:

  • the base of the array; and
  • the offset from that base.

You're actually lucky to have chosen an even number of characters, otherwise you'd probably keep going beyond the end of str1 (by missing the \0), resulting in all sorts of fun and hilarity :-)

You should increment one or the other, such as with:

char *mystrcat(char *str1, char *str2) {
    int i = 0;
    while(str1[i] != '\0')
        i++;
    while(*str2 != '\0')
        str1[i++] = *str2++;
    str1[i] = '\0';
    return str1;
}

The reason why you only get the first string after the concatenation, is the i++ after the first loop (which I've removed from the above code).

When you exit that loop, i is the index of the str1 terminator character so, an i++ at that point will jump over it. That means that you'll append str2 after that terminator:

qwerty<nul>asdf<nul>

Hence the string will only be qwerty because C strings always stop at the first terminator.


I often find it's useful to be able to start with a memory map and variable register (on paper), then run the code in your head, changing variables along the way. It helps to understand how your program will work. You can start with something like:

                 1         2
Index: 012345678901234567890
str1:  qwerty_
str2:  asdf_
i:     0

Then, each line of code in your head will result in i changing, or the string memory blocks changing (the _ at the end indicates the string terminator).

Upvotes: 2

Jorenar
Jorenar

Reputation: 2884

Don't increment the string pointers. Do just

while (str1[i]) {
    ++i;
}

And start with iterating str2 with another variable, from 0.

What you are doing currently is basically: str1[12] = str[6]

When you want: str1[6] = str2[0]

Upvotes: 1

Related Questions