best way to add char* prefix to existing char* in C [duplicate] - c

This question already has answers here:
How do I concatenate const/literal strings in C?
(17 answers)
Closed 8 years ago.
What I have:
char * a = "world";
char * b = "Hello";
What I need is:
char * a = "Hello World";
I need to add b before a.
Is there any function that doing it?

It can be done easily as shown below:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
char * a = "world";
char * b = "Hello";
char *c = malloc(strlen(a)+strlen(b)+1);
strcpy(c,b);
strcat(c,a);
printf("%s\n",c);
free(c);
}

You could use strcat(3), snprintf(3) or asprintf(3)
With strcat you need to check against buffer overflow (using strlen(3)...)
With strcat & snprintf, you need to pre-allocate the array.
With asprintf you are given a heap-allocated buffer as a result, and you'll need to free it appropriately.
So, using strcat and a fixed-size buffer buf:
char buf[64];
if (strlen(a)+strlen(b)<sizeof(buf)) {
strcpy(buf, a);
strcat(buf, b);
}
// now buf contains "worldhello"
Alternatively you might use a heap-allocated buffer: char*buf = malloc(strlen(a)+strlen(b)+1); but don't forget to check against malloc failure: if (!buf) { perror("malloc buf"); exit(EXIT_FAILURE); }; and then do the strcpy & strcat as before. Of course you'll need to free(buf) later at the appropriate time. Notice that you could keep int lena=strlen(a); then strcpy(buf+lena,b) instead of calling strcat.
Using snprintf and a fixed-size buffer buf (no need to check against buffer overflow since snprintf is given the buffer size):
char buf[54];
int len= snprintf(buf, sizeof(buf), "%s%s", a, b);
// now buf contains "worldhello" and len contains the required length
The nice thing about snprintf is that is understands printf format control strings (e.g. %d for integer in decimal, %g for floating point in scientific notation, etc...)
Using asprintf (on systems like Linux which provide it)
char* buf = asprintf("%s%s", a, b);
But you need to call free(buf) at the appropriate moment to avoid a memory leak.
See also strdup(3), fmemopen(3) and open_memstream
In your question you should swap a and b

Related

Dereference C string pointer into variable

I have the following simple program which creates a pointer to the first character of a string:
char str[] = "Hello world";
char *p = &str[0];
How can I then get this string back into a variable using only the pointer?
Dereferencing the pointer just gives the first character of the string - as somewhat expected - so I'm assuming that there is no 'simple' way to achieve this and it will instead require writing extra code.
The current way I would approach this would be as follows:
Iterate from the pointer until a null terminator is reached to find the length of the string
Create a new char array with this length
Iterate through again inserting characters into this array
Is there a library function to achieve this, or if not, a simpler way that doesn't involve iterating twice?
Yes you have to "do it by hand". Because there are no objects in C - you need to take care of all that happens in the code.
You can use malloc, strlen and memcpy:
char str[] = "Hello world";
char *p = malloc(strlen(str) + 1);
if (!p) { abort(); }
memcpy(p, str, strlen(str) + 1);
You can use strcpy and forget about one strlen:
char *p = malloc(strlen(str) + 1);
if (!p) { abort(); }
strcpy(p, str);
Or you can use strdup from POSIX or a C extension:
char *p = strdup(str);
if (!p) { abort(); }
...
Is there a library function to achieve this, or if not, a simpler way that doesn't involve iterating twice?
As said in comment, strdup() will do exactly what you want. But here there is another problem (by your point of view): strcpy() will iterate the string twice, because there is no other way to duplicate a string.
By definition, strings in C are a sequence of characters somewhere in memory, with the last one character being a NUL (with single L), the value 0 (in a char). References to strings are pointers to the first character in the sequence depicted above. Note that two different strings can point to the same memory (they are not so different then...), or a string can point into the middle of another. These two cases are somewhat particular but not uncommon. The memory for strings must be managed by the programmer, who is the only one to know where allocate and deallocate space for strings; functions like strcpy() do nothing special in this regard, they are (presumably) well written and optimized, so maybe to copy a string the behavior is not plain as I depicted it before, but the idea is the same.
try this code:
#include "stdio.h"
int main(){
char str[] = "Hello world";
int count = 12;
char (*p)[12] = &str;
printf("%c\n",(*p)[0]);
printf("%c\n",(*p)[1]);
printf("%c\n",(*p)[2]);
printf("%c\n",(*p)[3]);
printf("%s\n",(*p));
}
Here's how I would make a copy of a string using only the standard library functions:
#include <stdio.h> // printf
#include <stdlib.h> // malloc
#include <string.h> // strcpy
int main(void)
{
char str[] = "Hello world"; // your original string
char *p = (char *)malloc(strlen(str) + 1); // allocate enough space to hold the copy in p
if (!p) { // malloc returns a NULL pointer when it fails
puts("malloc failed.");
exit(-1);
}
strcpy(p, str); // now we can safely use strcpy to put a duplicate of str into p
printf("%s\n", p); // print out this duplicate to verify
return 0;
}

How can I concatenate strings in C? [duplicate]

This question already has answers here:
Appending strings in C
(6 answers)
Closed 8 years ago.
How can I concatenate strings this way?
For example:
char *txt = "Hello";
txt=txt+"World!";
I tried it but it wasn't.
txt is a pointer and memory should be allocated to it.
It is good to have the below checks
The amount of memory which needs to allocated can be calculated by
size_t size = strlen("Hello") + strlen("World");
char *txt = malloc(size + 1);
Check the return value of malloc() before accessing it.
if(txt != NULL)
Dynamically this can be done:
char *txt = malloc(size+1); /* Number of bytes needed to store your strings */
strcpy(txt,"Hello");
strcat(txt,"World");
The allocated memory should be freed after using it like
free(txt);
Alternatively you can have
char txt[30];
strcpy(txt,"Hello");
strcat(txt,"World");
here is classic way to concat strings:
char *txt = "Hello";
char *txt2 = "World!";
char *txt3 = malloc(strlen(txt) + strlen(txt2) + 1); // don't forget about ending \0
strcpy(txt3,"Hello");
strcat(txt3,"World");
don't forget to free allocated memory
Avoid the memory leak using malloc - use arrays
i.e.
char txt[100];
strcpy(txt, "hello");
strcat(txt, "world");
This is covered in all C text books
To do it properly you have many options you could declare an array of char and use what #EdHeal suggested, but you should know in advance the length of both strings combined or you can overflow the array, and that is undefined behavior.
Or, you cold use dynamic memory allocation, but that is more complicated than just calling malloc and strcpy since you need to be very careful.
First of all, you have to know that in c strings require a '\0' character at the end of the string so when you allocate memory you should account for it.
The length of the string is obtained by means of the strlen function, which you should try to use only once per string since it computes the length, so it's expensive and it's redundant to use it more than once for the same string.
When using malloc the system may run out of memory, in that case malloc will return a special value NULL, if it did, any operation on the resulting pointer will be undefined behavior.
Finally when you no longer need the constructed string, you have to release resources to the operating system, usgin free.
This is an example of what I mean
char *text;
size_t lengthOfHello;
size_t lengthOfWorld;
lengthOfHello = strlen("Hello");
lengthOfWorld = strlen("World");
text = malloc(1 + lengthOfHello + lengthOfWorld);
if (text != NULL)
{
strcpy(text, "Hello");
strcat(text, "world");
/* ... do stuff with text ... */
free(text);
}
the terminating '\0' is already in "Hello" and it will be copied by strcpy.

Global variable in main with concatenation? [duplicate]

This question already has answers here:
How do I concatenate const/literal strings in C?
(17 answers)
Closed 9 years ago.
I realize the following will not work but is there an equivalent?
const char *foo = "foo";
static char *end = sprintf ("%s_bar", foo);
What I want to do is concatenate strings and then make that concatenated string a static variable so that it becomes a global variable. Also I like not having to assign memory to a char. I need this to go in main() because I need to use a function (sprintf) to merge two strings.
Superficially, you could revise the code as follows:
#define FOO_INITIALIZER "foo"
const char *foo = FOO_INITIALIZER;
static char *end = FOO_INITIALIZER "_bar";
I'm not sure how much it buys you, but it should compile and avoids repetition of the strings. It uses adjacent string literal concatenation, which is standard in C89 and later (but not in pre-standard compilers).
I think you can do it with the stringizing operator.
#define STR_CONCAT(x, y) #x#y
static char *end = STR_CONCAT(foo, _bar);
int main(void)
{
printf("%s", end); // prints out "foo_bar"
getchar();
return 0;
}
sprintf is declared as int sprintf(char *str, const char format, ...); char* str is the buffer to which the output will be written, however malicious users might put more to that buffer than the sizeof that buffer therefore one can also use snprintf which includes a parameter that contains the size of the output buffer so bufferoverflows will not happen. What you should note it returns the number of bytes written, therefore you cannot assign it to a char or char[].
const char* foo = "foo";
static char end[BUFSIZE];
snprintf(end, BUFSIZE, ""%s_bar", foo);
I prefer to use snprintf for it doesn't as easily result in a buffer overflow which is a security error. Now it can atmost print BUFSIZ characters to end you can look if the concatenation succeeded if snprintf returns strlen("s_bar") + strlen("foo");
What you can also do is:
char end[BUFSIZE] = "foo_";
strncat( end, "_bar", BUFSIZ);
which is perhaps more what you like.

Can't declare two character pointers [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
why does c allow initialization of string without declaration?
I am trying this rather simple code:
#include<stdio.h>
void copy(char *,char *);
main() {
char *name;
char *surname;
printf("Enter name: ");
scanf("%s",name);
printf("%s",name);
}
But for some reason, after I enter a name and press Enter, the program hangs and gives a message like Program has stopped working. However when I remove the 2nd character pointer declaration, that is the char *surname;, it works just as expected. What is the problem here?
You have not allocated memory for the pointers, so the scanf accesses arbitrary unspecified memory, which is undefined behaviour.
You need to pass pointers to sufficiently large memory blocks to scanf, either declare
char s1[100], s2[100];
(if 100 is large enough), or malloc memory
char *s1 = malloc(100);
char *s2 = malloc(100);
if (!s1 || !s2) {
// malloc failure
exit(EXIT_FAILURE);
}
You are writting into unallocated memory. That is undefined behavior,
You can do 2 things here:
declare your arrays of chars as having a fixed size at compile-time like this: char name[100]; (which means you can't change their size at runtime)
allocate room for char *name using malloc() or calloc() functions in stdlib.h
In any case you absolutely have to make sure you only allow the user to input the amount of bytes you allocated, otherwise bad things can and will happen!
A small study on what an evil person can (and will ;) do if you fail to define said boundaries can be found here: http://www.cultdeadcow.com/cDc_files/cDc-351/
Because you didn't allocate memory for it, and the string you put in it screws the code of the program. Try to use sscanf and getline:
#include <stdio.h>
int main()
{
int nbytes = 100;
char *my_string;
int int1, int2, int3;
int args_assigned;
args_assigned = 0;
while (args_assigned != 3)
{
puts ("Please enter three integers separated by whitespace.");
my_string = (char *) malloc (nbytes + 1);
getline (&my_string, &nbytes, stdin);
args_assigned = sscanf (my_string, "%d %d %d", &int1, &int2, &int3);
if (args_assigned != 3)
puts ("\nInput invalid!");
}
printf ("\nThanks!\n%d\n%d\n%d\n", int1, int2, int3);
return 0;
}
check out this:
Reading in a variable length string user input in C
and this :
http://en.wikipedia.org/wiki/Buffer_overflow
You declare a pointer and do not give it a valid memory address, it points to a random addrss. You cannot read or write with this pointer. Pointers should be used like this:
char s1[100],s2[100];
char * name=s1;
char * surname=s2;

String concatenation in C

if I want to construct a const char * out of several primitive type arguments, is there a way to build the string using a similar to the printf?
You're probably looking for snprintf.
int snprintf(char *str, size_t size, const char *format, ...);
A simple example:
char buffer[100];
int value = 42;
int nchars = snprintf(buffer, 100, "The answer is %d", value);
printf("%s\n", buffer);
/* outputs: The answer is 42 */
GNU has an example too.
Just to add, you don't actually need to use snprintf - you can use the plain old sprintf (without the size argument) but then it is more difficult to ensure only n characters are written to the buffer. GNU also has a nice function, asprintf which will allocate the buffer for you.
You can use sprintf, which is exactly like printf except the first parameter is a buffer where the string will be placed.
Example:
char buffer[256];
sprintf(buffer, "Hello, %s!\n", "Beta");

Resources