painterofthewind
painterofthewind

Reputation: 123

Appending strings in C

How do I combine multiple strings. For example,

char item[32];
scanf("%s", item);
printf("Shopping list: %s\n", item); //I want to combine this string 
char string_2[] = "To do list: Sleep\n"; // with this string 
char hw[32];
scanf("%s", hw); 
printf("Homework: %s\n", hw); // and this string

So they will print like the following,

Shopping list: (item)

To do list: Sleep

Homework: (hw)


But I don't want to give printf orders separately like the code above, but rather combine the strings and call printf at the end/


How will I able to do this since I cannot save something like this into a separate string, char string1 = ("Shopping list: %s \n", item)

Upvotes: 2

Views: 2495

Answers (6)

Christophe Quintard
Christophe Quintard

Reputation: 2698

Consider using the great but unknown open_memstream() function.

FILE *open_memstream(char **ptr, size_t *sizeloc);

Example of usage :

// open the stream
FILE *stream;
char *buf;
size_t len;
stream = open_memstream(&buf, &len);

// write what you want with fprintf()
char item[32];
scanf("%s", item);
fprintf(stream, "Shopping list: %s\n", item);
char string_2[] = "To do list: Sleep\n";
fprintf(stream, "%s\n", string_2);
char hw[32];
scanf("%s", hw); 
fprintf(stream, "Homework: %s\n", hw);

// close the stream, the buffer is allocated and the size is set !
fclose(stream);
printf ("the result is '%s' (%d characters)\n", buf, len);
free(buf);

Let the kernel manage the buffer allocation, it does it better than you !

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753615

There are multiple issues I'm about to ignore (sequencing of input and output; error handling for input; buffer overflows on input; single words vs multiple words in an entry, etc), but:

char item[32];
scanf("%s", item);
char hw[32];
scanf("%s", hw);
char string_2[] = "To do list: Sleep\n";

printf("Shopping list: %s\n%sHomework: %s\n", item, string_2, hw);

This gives you a single printf() statement that provides the concatenated output. Clearly, the concatenation is on the output file (standard output) and not directly in memory. If you want the strings concatenated in memory, then you have to go through some machinations to ensure there's enough memory to copy into, but you can then use snprintf() for the job instead of printf():

char item[32];
scanf("%s", item);
char hw[32];
scanf("%s", hw);
char string_2[] = "To do list: Sleep\n";

// This length does account for two extra newlines and a trailing null
size_t totlen = strlen(item) + strlen(homework) + sizeof(string_2) +
                sizeof("Shopping list: ") + sizeof("Homework: ");
char *conc_string = malloc(totlen);

snprintf(conc_string, totlen, "Shopping list: %s\n%sHomework: %s\n",
         item, string_2, hw);

Upvotes: 1

Dietrich Epp
Dietrich Epp

Reputation: 213308

Processing raw strings in C is always ugly. You have to do two steps to concatenate strings:

  1. Allocate memory for the new string.

  2. Copy the source strings into your new buffer.

As a lesson, please note that there are already three different answers to this question with three different buffer overrun errors.

Here is a function which concatenates two strings and returns a new string:

char *astrcat(const char *x, const char *y)
{
    size_t nx = strlen(x), ny = strlen(y);
    char *z = malloc(nx + ny + 1);
    if (!z)
        return NULL;
    memcpy(z, x, nx);
    memcpy(z + nx, y, ny + 1);
    return z;
}

You can expand this to work with three strings, or you can just call it twice. Sane folk tend to use a library or make extensive use of fixed-size buffers.

Alternative: With fixed-size buffers and snprintf, you get safety and ease of use but you're stuck with fixed size buffers.

const char *x = ..., *y = ...;
char buf[100];
snprintf(buf, sizeof(buf), "%s%s", x, y);

If you don't have snprintf, then you're probably using MSVC, which has _snprintf which is almost the same but doesn't always nul-terminate the output.

Don't use strcat or strcpy: There are very few circumstances in which strcat is acceptable:

char buf[100];
strcpy(buf, x); // buffer overflow
strcat(buf, y); // buffer overflow

Don't use sprintf: It also overflows:

char buf[100];
sprintf(buf, "%s%s", x, y); // buffer overflow

Upvotes: 1

Parag Bafna
Parag Bafna

Reputation: 22930

use strcpy and strcat

char item[] = "Shopping list";
char hw[] = "To do list: Sleep \n";
char* itemhw;
itemhw = malloc(strlen(item)+strlen(hw)+1);
strcpy(itemhw, item);
strcat(itemhw, hw); 
free(itemhw);

Upvotes: 2

Myforwik
Myforwik

Reputation: 3588

You can use sprintf:

char combinedstring[100];
sprintf(combinedstring,"%s %s %s",item,string_2,hw);

You can also look up the string.h header and its functions.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409166

You concatenate the strings, preferably with the strcat function.

But make sure that the destination string you concatenate into is large enough to fit everything (including the terminating '\0' character).

Upvotes: 2

Related Questions