68

How do I append a single char to a string in C?

i.e

char* str = "blablabla";
char c = 'H';
str_append(str,c); /* blablablaH */
1
  • With the proviso that your definition of a string in line 1 needs to be a char array with enough memory allocated to it (as detailed in the answers), try strncat(str,&c,1); for the actual appending. Commented Apr 23, 2012 at 11:49

12 Answers 12

47
char* str = "blablabla";     

You should not modify this string at all. It resides in implementation defined read only region. Modifying it causes Undefined Behavior.

You need a char array not a string literal.

Good Read:
What is the difference between char a[] = "string"; and char *p = "string";

Sign up to request clarification or add additional context in comments.

Comments

47

To append a char to a string in C, you first have to ensure that the memory buffer containing the string is large enough to accomodate an extra character. In your example program, you'd have to allocate a new, additional, memory block because the given literal string cannot be modified.

Here's a sample:

#include <stdlib.h>

int main()
{
    char *str = "blablabla";
    char c = 'H';

    size_t len = strlen(str);
   
    /* one for extra char, one for trailing zero */
    char *str2 = malloc(len + 1 + 1);

    strcpy(str2, str);
    str2[len] = c;
    str2[len + 1] = '\0';

    printf("%s\n", str2); /* prints "blablablaH" */

    free(str2);
}

First, use malloc to allocate a new chunk of memory which is large enough to accomodate all characters of the input string, the extra char to append - and the final zero. Then call strcpy to copy the input string into the new buffer. Finally, change the last two bytes in the new buffer to tack on the character to add as well as the trailing zero.

3 Comments

The comment about using sizeof is incorrect. sizeof str is either 4 or 8 depending on whether you are compiling 32 or 64 bit code.
Also, always use a format specifier in printf. Imagine if str contained a %s char sequence in it.
@JeremyP The sizeof comment is indeed imprecise. I meant that you can call sizeof("blablablah"), I'll just remove the comment altogether since the compiler may well be smart enough to notice that it can const-fold the call. As for the format specifier - you're correct of course, a very embarrasing error. I'll update my answer.
10

The Original poster didn't mean to write:

  char* str = "blablabla";

but

  char str[128] = "blablabla";

Now, adding a single character would seem more efficient than adding a whole string with strcat. Going the strcat way, you could:

  char tmpstr[2];
  tmpstr[0] = c;
  tmpstr[1] = 0;
  strcat (str, tmpstr);

but you can also easily write your own function (as several have done before me):

  void strcat_c (char *str, char c)
  {
    for (;*str;str++); // note the terminating semicolon here. 
    *str++ = c; 
    *str++ = 0;
  }

Comments

6

If Linux is your concern, the easiest way to append two strings:

char * append(char * string1, char * string2)
{
    char * result = NULL;
    asprintf(&result, "%s%s", string1, string2);
    return result;
}

This won't work with MS Visual C.

Note: you have to free() the memory returned by asprintf()

4 Comments

If you have the non-standard asprintf function; it's not defined either by the C language or by POSIX.
Aren't you returning a reference to local variable?
I never had a problem with it, maybe asprintf allocs the memory.
@Abhishek asprintf mallocs enough space to put the resultant string in it. Apparently, it is available in the GNU glibc and most versions of BSD (counting OS X as a version of BSD).
5

you can use of strcat in string.h standard header but don't pass a char as second argument , use following code instead

void append_str(char str[] , char c){
     auto char arr[2] = {c , '\0'};
     strcat(str , arr);
}

2 Comments

Or just strcat(str, (char[2]){c, '\0'}) could be used. Isn't using auto redundant?
strncat(str, &c, 1) works too.
4

I do not think you can declare a string like that in c. You may only do that for const char* and of course you can not modify a const char * as it is const.

You may use dynamic char array but you will have to take care of the reallocation.

EDIT: in fact this syntax compiles correctly. Still you can should not modify what str points to if it is initialized in the way you do it (from string literal)

5 Comments

char *ptr = "string" is perfectly valid in C.
@Als - yes that's right. I thought it is not but it seems it's ok. However you still can not modify the array.
Yes, You cannot modify the string literal it's not an array to begin with.
@Als again I agree - it is a literal :)
@AlokSave String literals are arrays.
4

Create a new string (string + char)

#include <stdio.h>    
#include <stdlib.h>

#define ERR_MESSAGE__NO_MEM "Not enough memory!"
#define allocator(element, type) _allocator(element, sizeof(type))

/** Allocator function (safe alloc) */
void *_allocator(size_t element, size_t typeSize)
{
    void *ptr = NULL;
    /* check alloc */
    if( (ptr = calloc(element, typeSize)) == NULL)
    {printf(ERR_MESSAGE__NO_MEM); exit(1);}
    /* return pointer */
    return ptr;
}

/** Append function (safe mode) */
char *append(const char *input, const char c)
{
    char *newString, *ptr;

    /* alloc */
    newString = allocator((strlen(input) + 2), char);
    /* Copy old string in new (with pointer) */
    ptr = newString;
    for(; *input; input++) {*ptr = *input; ptr++;}
    /* Copy char at end */
    *ptr = c;
    /* return new string (for dealloc use free().) */
    return newString;
}

/** Program main */
int main (int argc, const char *argv[])
{
    char *input = "Ciao Mondo"; // i am italian :), this is "Hello World"
    char c = '!';
    char *newString;

    newString = append(input, c);
    printf("%s\n",newString);
    /* dealloc */
    free(newString);
    newString = NULL;

    exit(0);
}

              0   1   2   3    4    5   6   7   8   9  10   11
newString is [C] [i] [a] [o] [\32] [M] [o] [n] [d] [o] [!] [\0]

Don't alter the array size ([len +1], etc.) without know its exact size, it may damage other data. alloc an array with the new size and put the old data inside instead, remember that, for a char array, the last value must be \0; calloc() sets all values to \0, which is excellent for char arrays.

I hope this helps.

Comments

2

C does not have strings per se -- what you have is a char pointer pointing to some read-only memory containing the characters "blablabla\0". In order to append a character there, you need a) writable memory and b) enough space for the string in its new form. The string literal "blablabla\0" has neither.

The solutions are:

1) Use malloc() et al. to dynamically allocate memory. (Don't forget to free() afterwards.)
2) Use a char array.

When working with strings, consider using strn* variants of the str* functions -- they will help you stay within memory bounds.

1 Comment

But never use strncpy. It's not a string function (despite its name) and only causes trouble.
2

You can use strncat()

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

int main(void){
  char hi[6];
  char ch = '!';
  strcpy(hi, "hello");

  strncat(hi, &ch, 1);
  printf("%s\n", hi);
}

Comments

0

You can use strncat() with a pointer to your char (but first check if the buffer is large enough to store the resulting string):

char myString[100] = "Feli";
char toAppend = 'x';
// do something here to check if the buffer is large enough...
strncat(myString, &toAppend, 1);

Comments

-3

In my case, this was the best solution I found:

snprintf(str, sizeof str, "%s%c", str, c);

3 Comments

That looks like undefined behavior to me. I don't think you're allowed to pass the target argument str as one of the arguments of the format string ("%s...", str, ...).
@melpomene if you have declared it before, of course that you can
No, it is undefined behavior: "If copying takes place between objects that overlap, the behavior is undefined." (7.9.6.5 in C90 and 7.19.6.5 in C99)
-4

here's it, it WORKS 100%

char* appending(char *cArr, const char c)

{

int len = strlen(cArr);

cArr[len + 1] = cArr[len];

cArr[len] = c;

return cArr;


}

2 Comments

That works only if the string pointed to by cArr is writable and if it has enough room to add another character.
-1 since it only works "100%" for very small values of "100".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.