Advertisement
Advertisement


How do I concatenate const/literal strings in C?


Question

I'm working in C, and I have to concatenate a few things.

Right now I have this:

message = strcat("TEXT ", var);

message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));

Now if you have experience in C I'm sure you realize that this gives you a segmentation fault when you try to run it. So how do I work around that?

2017/05/22
1
356
5/22/2017 5:41:31 PM

Accepted Answer

In C, "strings" are just plain char arrays. Therefore, you can't directly concatenate them with other "strings".

You can use the strcat function, which appends the string pointed to by src to the end of the string pointed to by dest:

char *strcat(char *dest, const char *src);

Here is an example from cplusplus.com:

char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");

For the first parameter, you need to provide the destination buffer itself. The destination buffer must be a char array buffer. E.g.: char buffer[1024];

Make sure that the first parameter has enough space to store what you're trying to copy into it. If available to you, it is safer to use functions like: strcpy_s and strcat_s where you explicitly have to specify the size of the destination buffer.

Note: A string literal cannot be used as a buffer, since it is a constant. Thus, you always have to allocate a char array for the buffer.

The return value of strcat can simply be ignored, it merely returns the same pointer as was passed in as the first argument. It is there for convenience, and allows you to chain the calls into one line of code:

strcat(strcat(str, foo), bar);

So your problem could be solved as follows:

char *foo = "foo";
char *bar = "bar";
char str[80];
strcpy(str, "TEXT ");
strcat(str, foo);
strcat(str, bar);
2015/03/16
399
3/16/2015 5:31:02 PM


Folks, use strncpy(), strncat(), or snprintf().
Exceeding your buffer space will trash whatever else follows in memory!
(And remember to allow space for the trailing null '\0' character!)

2011/12/07

Strings can also be concatenated at compile time.

#define SCHEMA "test"
#define TABLE  "data"

const char *table = SCHEMA "." TABLE ; // note no + or . or anything
const char *qry =               // include comments in a string
    " SELECT * "                // get all fields
    " FROM " SCHEMA "." TABLE   /* the table */
    " WHERE x = 1 "             /* the filter */ 
                ;
2015/09/19

Also malloc and realloc are useful if you don't know ahead of time how many strings are being concatenated.

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

void example(const char *header, const char **words, size_t num_words)
{
    size_t message_len = strlen(header) + 1; /* + 1 for terminating NULL */
    char *message = (char*) malloc(message_len);
    strncat(message, header, message_len);

    for(int i = 0; i < num_words; ++i)
    {
       message_len += 1 + strlen(words[i]); /* 1 + for separator ';' */
       message = (char*) realloc(message, message_len);
       strncat(strncat(message, ";", message_len), words[i], message_len);
    }

    puts(message);

    free(message);
}
2008/11/21

Do not forget to initialize the output buffer. The first argument to strcat must be a null terminated string with enough extra space allocated for the resulting string:

char out[1024] = ""; // must be initialized
strcat( out, null_terminated_string ); 
// null_terminated_string has less than 1023 chars

It is undefined behaviour to attempt to modify string literals, which is what something like:

strcat ("Hello, ", name);

will attempt to do. It will try to tack on the name string to the end of the string literal "Hello, ", which is not well defined.

Try something this. It achieves what you appear to be trying to do:

char message[1000];
strcpy (message, "TEXT ");
strcat (message, var);

This creates a buffer area that is allowed to be modified and then copies both the string literal and other text to it. Just be careful with buffer overflows. If you control the input data (or check it before-hand), it's fine to use fixed length buffers like I have.

Otherwise, you should use mitigation strategies such as allocating enough memory from the heap to ensure you can handle it. In other words, something like:

const static char TEXT[] = "TEXT ";

// Make *sure* you have enough space.

char *message = malloc (sizeof(TEXT) + strlen(var) + 1);
if (message == NULL)
     handleOutOfMemoryIntelligently();
strcpy (message, TEXT);
strcat (message, var);

// Need to free message at some point after you're done with it.
2016/02/22

Source: https://stackoverflow.com/questions/308695
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]