user3340536
user3340536

Reputation: 43

String concatenation. C

All of the code below on C.

Both the code snippet below are compiled, but the difference is that the second program crashes at startup.

One:

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

void main() {
    char *foo = "foo";
    char *bar = "bar";
    char *str[80];;
    strcpy (str, "TEXT ");
    strcat (str, foo);
    strcat (str, bar);
}

Two:

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

void main() {
    char *foo = "foo";
    char *bar = "bar";
    char *str="";
    strcpy (str, "TEXT ");
    strcat (str, foo);
    strcat (str, bar);
}

The difference is that in the first case, said the size of the str string, while the second is not. How to make string concatenation without a direct indication of the size of the string str?

Upvotes: 4

Views: 258

Answers (7)

Darth Shirr
Darth Shirr

Reputation: 587

You'll have to allocate memory before copying. The first defines the size so as 80 char *str = new char[10]; could also be a method of allocation. malloc function could also be used to allocate memory.

Here are some references that might help you

http://www.cplusplus.com/reference/cstdlib/malloc/ http://www.cplusplus.com/reference/cstdlib/calloc/

Upvotes: 1

Dabo
Dabo

Reputation: 2373

Both programs are wrong, the first provokes undefined behavior exactly as the second one. char *str[80]; is array of pointers which you pass to functions ( strcpy, strcat) as first argument, while the first argument for those functions should be char *. Possible solution for this issue to define str as char str[80];

The issue with the second program is that char *str=""; is a pointer to read only piece of memory, which can't be changed.In this case one of possible solutions can be :

 char* str = malloc(80);
 strcpy(str,"");
 strcpy (str, "TEXT ");
 strcat (str, foo);
 strcat (str, bar);

Upvotes: 1

tsragravorogh
tsragravorogh

Reputation: 3153

In the second version you have set char *str=""; this is equivalent to allocating an empty string on the stack with 1 byte which contains null for end of string. Had you written char*str="0123456789", you would have allocated 11 bytes on the stack the first 10 of which would have been "0123456789" and the 11th byte would have been null. If you try to copy more than allocated bytes to the str, your program might crash. So either allocate dynamically enough memory, or statically.

Upvotes: 1

ajay
ajay

Reputation: 9680

The difference is that in the first case, said the size of the str string, while the second is not.

No. In the first program, the following statement

char *str[80];

defines str to be an array of 80 pointers to characters. What you need is a character array -

char str[80];

In the second program,

char *str="";

defines str to be a pointer to the string literal "", not an array. Arrays and pointers are different types.

Now, the second program crashes because

char *str="";

defines str to be a pointer to a string literal. The first argument of strcpy should be a pointer to a buffer which is large enough for the string to be copied which is pointed to by its second argument.

However, str points to the string literal "" which is allocated in read-only memory. By passing str to strcpy, it invoked undefined behaviour because strcpy tries to modify it which is illegal. Undefined behaviour means the behaviour is unpredictable and anything can happen from program crash to due to segfault (illegal memory access) or your hard drive getting formatted. You should always avoid code which invoked undefined behaviour.

How to make string concatenation without a direct indication of the size of the string str?

The destination string must be large enough to store the source string else strcpy will overrun the buffer pointed to by its first argument and invoke undefined behaviour due to illegal memory access. Again, the destination string must have enough space for the source string to be appended to it else strcat will overrun the buffer and again cause undefined behaviour. You should ensure against this by specifying the correct size of the string str in this case.

Upvotes: 3

size_t len1 = strlen(first);
size_t len2 = strlen(second);

char * s = malloc(len1 + len2 + 2);
memcpy(s, first, len1);
s[len1] = ' ';
memcpy(s + len1 + 1, second, len2 + 1); // includes terminating null

Did I do good?

Upvotes: 1

Mahonri Moriancumer
Mahonri Moriancumer

Reputation: 6003

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

void main() {
    char *foo = "foo";
    char *bar = "bar";
    char *str=NULL;
    size_t strSize = strlen(foo)+strlen(bar)+strlen("TEXT ")+1;

    str=malloc(strSize);
    if(NULL==str)
       {
       fprintf(stderr, "malloc() failed.\n");
       goto CLEANUP;
       }

    strcpy (str, "TEXT ");
    strcat (str, foo);
    strcat (str, bar);

CLEANUP

    if(str)
       free(str);        
    }

Upvotes: 1

HelloWorld123456789
HelloWorld123456789

Reputation: 5359

Change to:

One:

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

void main() {
    char *foo = "foo";
    char *bar = "bar";
    char str[80];
    strcpy (str, "TEXT ");
    strcat (str, foo);
    strcat (str, bar);
}

Two:

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

void main() {
    char *foo = "foo";
    char *bar = "bar";
    char str[80]="";
    strcpy (str, "TEXT ");
    strcat (str, foo);
    strcat (str, bar);
}

Upvotes: 2

Related Questions