How to concatenate elements of char* array while using loop? Inexplicable behaviour of strcat.

Hello,guys.Need your advice. I'm unsuccessfully trying to concatenate two strings, two elements of a pointer array by using strcat in for loop. I just can't comprehend why strcat behaves so odd. Here is the code and program output. Using strcat in the same output statement with the elements of the arrays affects them the way i cannot understand even if i use concatenation AFTER outputing the elements. If you know what's going on and how to use concatenation correctly please tell me. Thank you very much in advance.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//--------------------------------------------------------------------------
#include<iostream.h>
#include<conio>
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
  int i;
  char *mass [] ={"one","two","three"};
  char *mass1 []={"four","five","six"};

  for (i=0;i<3;i++)
       {cout << mass[i]<<" "<<mass1[i]<<endl;
        //cout << strcat(mass[i],mass1[i])<<endl;
        }

        cout <<endl << endl;
   for (i=0;i<3;i++)
       cout <<mass[i]<<"  "<<mass1[i]<<"  " << strcat (mass[i],mass1[i])<<endl;

   getch();
        return 0;
}
//--------------------------------------------------------------------------- 

one four
two five
three six


onefour  four  onefour
ourfive  five  ourfive
ivesix  six  ivesix
since I know nothing about working with C strings or strcat and cant be bothered to look them up my first question would be this, is there any real reason to use char*s? std::strings make this kind of thing easier, and a lot safer too.
Last edited on
If you want to use strcat no matter what, that's ok but in that case at least use standard C++ with the rest.

1) You do not include string.h, which is the header file in which strcat is defined.
2) You DO include conio.h, which you don't need in this example
3) You do include iostream.h, which is deprecated since... well, a long time. Include iostream (without the.h) instead.

The problem in your case is the way you pass arguments to strcat and what an array of const char* looks in C++.

The problem is, your arrays look like that in memory:

mass: "one\0two\0three\0"
mass1: "four\0five\0six\0"


strcat is declared like that:
char* strcat(char* dest, char* source);
It appends source to dest, and then returns dest.

In your case, after appending mass1[0] to mass[0], it looks like that:

mass: "onefour\0\0three\0"
mass1: "four\0five\0six\0"


If you don't understand why this happens, you are better off including <string> and using std::strings instead.
Last edited on
I just can't comprehend why strcat behaves so odd.
strcpy copies the content of one sequence of chars to another until it meets a null terminator. And strcat seeks to the null in the desination buffer/string, then behaves like strcpy.

char *mass [] ={"one","two","three"};mass is declared to be an array of pointers to char*. The char*'s are really constant as they're initialised at load time, and if you declared them as such the compiler would caught your mistake.

What mistake?
strcpy and strcat copy from a source buffer to a destination buffer. The only check is the check for a null terminator in the source buffer/string. There is no way it can check if there's enough space in the destination.

Your call strcat(mass[i], mass1[i]) attempts to append to the string at mass[i]. But there is no space to append the string, so you overwrite whatever is in the following memory locations.

strcpy's destination much be a char*. If you had properly declared mass to be const char[] the compiler would have detected the type mismatch.

So those are your two errors.

And the fix? Declare mass and mass1 correctly. You need to create a temporary buffer that's large enough for the two strings, copy in the first one and contatenate the other. I've edited your code with the fix. I've removed the conio stuff and used the new stream library.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string.h>

int main(int argc, char* argv[])
{
  using namespace std;

  const char *mass[] = {"one", "two", "three" };
  const char *mass1[]= {"four", "five", "six" };

  for (int i = 0; i < 3; ++i)
  {
    char buffer[16]; // large enough
    strcpy(buffer, mass[i]);
    strcat(buffer, mass1[i]);
    cout << mass[i] << "  " << mass1[i] << "  " << buffer << endl;
  }
  cout <<endl << endl;

  return 0;
}

Last edited on
Thanks a lot everyone
Topic archived. No new replies allowed.