char *str1 = malloc(256*sizeof(char));
char *str2 = "stack"
for (i=0;i<15;i++){
sprintf(str1,"%s%s",str1,str2);
}
printf("%s\n",str1);
I'm trying to concat str2 to str1 at each loop count. But this code segment works but vulnerable.
Whats the best way to concat them?
According to the CERT Secure Coding Guidelines, you need to use pointers to const when referring to string literals.
So, char *str2 = "stack" needs to be const char *str2 = "stack";.
This will make it immutable.
Additionally, you are using deprecated/obsolete functions. The secure function you should be using is strcat_s. For example,
Compliant Example
enum { BUFFERSIZE=256 };
void complain(const char *msg) {
static const char prefix[] = "Error: ";
static const char suffix[] = "\n";
char buf[BUFFERSIZE];
strcpy_s(buf, BUFFERSIZE, prefix);
strcat_s(buf, BUFFERSIZE, msg);
strcat_s(buf, BUFFERSIZE, suffix);
fputs(buf, stderr);
}
Read here about strcpy_s() and strcat_s().
If you want to use sprintf; something like this:
char *str1 = malloc(256*sizeof(char));
char *str2 = "stack";
*str1 = '\0';
for (i=0;i<15;i++){
snprintf(str1 + strlen(str1), 256 - strlen(str1), "%s", str2);
}
printf("%s\n",str1);
The standard C function for string concatenation is char * strncat ( char * destination, char * source, size_t num );.
Use strncat:
char *str1 = malloc(256*sizeof(char));
str1[0] = '\0';
char *str2 = "stack"
for (i=0;i<15;i++){
strncat(str1, str2, 256 - 1 - strlen(str2));
}
printf("%s\n",str1);
Related
why does the following string concatenation does not work?
main()
{
char *str1 = "United";
char *str2= "Front";
char *str3;
str3 = strcat(str1, str2 ) ;
printf("\n%s",str3 );
}
I got this problem in exercise questions in one of a book on pointers. The question mentions
[Q] Is the code correct if not why and also correct the code.
See my answer to the question concatenation of character arrays in c
You may not change string literals.
This statement
str3 = strcat(str1, str2 ) ;
tries to change the string literal str1 and moreover tries to write beyond the string literal.
To make a concatenated string you have to allocate a memory large enough to contain the both strings.
What you need is the following
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
const char *str1 = "United";
const char *str2 = "Front";
char *str3 = malloc( strlen( str1 ) + strlen( str2 ) + 1 );
strcpy( str3, str1 );
puts( strcat( str3, str2 ) );
free( str3 );
return 0;
}
The program output is
UnitedFront
When you write char* s = "something" a piece of read-only memory is allocated. More on this here.
The declaration of strcat looks like this:
char *strcat( char *dest, const char *src );
Basically what it will do is append src to dest, but since your destination, str1 does not have enough memory to hold both strings.
So what I would do is, either use snprintf with a pre-allocated buffer or:
char *str1 = "United";
char *str2 = "Front";
char *buf = calloc(strlen(str1) + strlen(str2) + 1, sizeof(char));
strncpy(buf, str1, strlen(str1));
strncat(buf, str2, strlen(str2));
printf("%s", buf);
Or with snprintf:
char *str1 = "United";
char *str2 = "Front";
int buf_len = strlen(str1) + strlen(str2) + 1;
char *buf = calloc(buf_len, sizeof(char));
snprintf(buf, buf_len, "%s%s", str1, str2);
The first parameter of strcat (str1 in your case) needs to have enough allocated memory to hold the concatenated string.
You can either create it with malloc or declare it as an array with a big enough size.
I have this function:
char *replace_str(char *str, char *orig, char *rep)
{
static char buffer[4096];
char *p;
if(!(p = strstr(str, orig)))
return str;
strncpy(buffer, str, p-str);
buffer[p-str] = '\0';
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
return buffer;
}
When I use it, it only changes the first instance of the character to be replaced. Is there any way i can make it get it to do this to all said characters?
If I understand correctly, you need a loop that reallocates the beginning of the string after the ending of your replacement string. Indeed, your function performs the action only once, since strstr returns a pointer to the first occurrence of the word orig in str.
EDIT: This may give you an idea of how to do it. I can't test it on this computer, so it might not work directly.
I did it using malloc, since static char shouldn't be used this way, in my opinion. It is supposed to store the values in buffer for a future use of the function. If you re-use this function, you would lose the previous return value of the function...
This is my way of doing it, there is certainly a more efficient way of doing it. The advantage of this function is that it adapts to any string length.
char *replace_str(char *str, char *orig, char *rep)
{
char *buffer;
char *previous_version;
char *p;
size_t occurring_position;
if (strcmp(orig, rep) == 0)
{
return(str);
}
buffer = strdup(str);
while ((p = strstr(buffer, orig)))
{
occuring_position = p - buffer;
previous_version = strdup(buffer);
free(buffer);
buffer = malloc(strlen(previous_version) + strlen(rep) - strlen(orig));
strcnpy(buffer, previous_version, occurring_position);
strcpy(buffer, rep);
strcpy(buffer + occurring_position + strlen(rep), previous_version + occurring_position + strlen(orig));
free(previous_version);
}
return (buffer);
}
How can I add '.' to the char Array := "Hello World" in C, so I get a char Array: "Hello World." The Question seems simple but I'm struggling.
Tried the following:
char str[1024];
char tmp = '.';
strcat(str, tmp);
But it does not work. It shows me the error: "passing argument 2 of ‘strcat’ makes pointer from integer without a cast"
I know that in C a char can be cast as int aswell. Do I have to convert the tmp to an char array aswell or is there a better solution?
strcat has the declaration:
char *strcat(char *dest, const char *src)
It expects 2 strings. While this compiles:
char str[1024] = "Hello World";
char tmp = '.';
strcat(str, tmp);
It will cause bad memory issues because strcat is looking for a null terminated cstring. You can do this:
char str[1024] = "Hello World";
char tmp[2] = ".";
strcat(str, tmp);
Live example.
If you really want to append a char you will need to make your own function. Something like this:
void append(char* s, char c) {
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
append(str, tmp)
Of course you may also want to check your string size etc to make it memory safe.
The error is due the fact that you are passing a wrong to strcat(). Look at strcat()'s prototype:
char *strcat(char *dest, const char *src);
But you pass char as the second argument, which is obviously wrong.
Use snprintf() instead.
char str[1024] = "Hello World";
char tmp = '.';
size_t len = strlen(str);
snprintf(str + len, sizeof str - len, "%c", tmp);
As commented by OP:
That was just a example with Hello World to describe the Problem. It
must be empty as first in my real program. Program will fill it later.
The problem just contains to add a char/int to an char Array
In that case, snprintf() can handle it easily to "append" integer types to a char buffer too. The advantage of snprintf() is that it's more flexible to concatenate various types of data into a char buffer.
For example to concatenate a string, char and an int:
char str[1024];
ch tmp = '.';
int i = 5;
// Fill str here
snprintf(str + len, sizeof str - len, "%c%d", str, tmp, i);
In C/C++ a string is an array of char terminated with a NULL byte ('\0');
Your string str has not been initialized.
You must concatenate strings and you are trying to concatenate a single char (without the null byte so it's not a string) to a string.
The code should look like this:
char str[1024] = "Hello World"; //this will add all characters and a NULL byte to the array
char tmp[2] = "."; //this is a string with the dot
strcat(str, tmp); //here you concatenate the two strings
Note that you can assign a string literal to an array only during its declaration.
For example the following code is not permitted:
char str[1024];
str = "Hello World"; //FORBIDDEN
and should be replaced with
char str[1024];
strcpy(str, "Hello World"); //here you copy "Hello World" inside the src array
I think you've forgotten initialize your string "str": You need initialize the string before using strcat. And also you need that tmp were a string, not a single char. Try change this:
char str[1024]; // Only declares size
char tmp = '.';
for
char str[1024] = "Hello World"; //Now you have "Hello World" in str
char tmp[2] = ".";
Suggest replacing this:
char str[1024];
char tmp = '.';
strcat(str, tmp);
with this:
char str[1024] = {'\0'}; // set array to initial all NUL bytes
char tmp[] = "."; // create a string for the call to strcat()
strcat(str, tmp); //
I want to do in C, what can be achieved in Java as follows
String str = "hello";
System.out.println(str + 'a');
I have written the following.
1. It doesn't work
2. Is there an easier way to do this in C, something that can be achieved in java in a single line.
#include <stdio.h>
char* charcat(char str[], char c);
int main(void)
{
char str[] = "hello";
printf("%s\n",charcat(str,'a'));
}
char* charcat(char str[], char c)
{
char newstr[] = {c,'\0'};
char temp[20];
strcpy(temp,str);
strcat(temp,newstr);
return temp;
}
EDIT :
I have edited based on ameyCU's response.
char* charcat(char str[], char c);
int main(void)
{
char str[] = "hello";
printf("%s\n",charcat(str,'a'));
}
char* charcat(char str[], char c)
{
char* temp;
char newstr[] = {c,'\0'};
temp = malloc((strlen(str) + 1)* sizeof(char));
strcpy(temp,str);
return strcat(temp,newstr);
}
EDIT 2:
char* charcat(char str[], char c);
int main(void)
{
char str[] = "hello";
char temp[20];
strcpy(temp,str);
printf("%s\n",charcat(temp,'a'));
}
char* charcat(char str[], char c)
{
char newstr[] = {c,'\0'};
return strcat(str,newstr);
}
I think what you were trying to do was this:
char* charcat(char str[], char c)
{
char newstr[] = {c,'\0'};
char *temp=(char *)malloc((strlen(str)+1+1)*sizeof(char));
strcpy(temp,str);
strcat(temp,newstr);
return temp;
}
make sure you free() the pointer.
You can use strcat() function
char str1[20]="hello";
strcat(str1,"c");
printf("%s",str1);
Problem is that you return a local variable.
return temp;
temp is local variable and its scope is just inside the function it is declared.
After concatenation -strcat(temp,newstr);
You can do this -
strcpy(str,temp);
return str;
But this will also change the contents of original array.
EDIT
To keep original array intact assign a pointer to string in function and return the pointer .
And also to use functions like strcpy and strcat you need to include string.h header.
This uses snprintf() to get the required length for the target string. Memory is allocated and then snprintf() creates the target string.
#include<stdio.h>
#include<stdlib.h>
char* charcat(char str[], char c);
int main ( ) {
char str[] = "hello";
char *output = NULL;
printf ( "str-> %s\n\n", str);
if ( ( output = charcat ( str, 'a'))) {//successful return of pointer
printf ( "output-> %s\n", output);
free ( output);//release memory
}
return 0;
}
char* charcat(char str[], char c)
{
char *temp = NULL;
int length = 0;
length = snprintf ( NULL, 0, "%s%c", str, c);//get required length
if ( ( temp = malloc ( length + 1))) {//allocate plus one for '\0'
snprintf ( temp, length + 1, "%s%c", str, c);//malloc succeeds make target
}
return temp;
}
It is always better to use strncat() instead of strcat to avoid buffer overflows.
#include <cstdio>
#include <cstring>
int main ()
{
char str[20] = "hello";
strncat (str, "a", sizeof(str) - strlen(str) - 1);
printf("%s",str);
return 0;
}
Output:
helloa
RUN SUCCESSFUL (total time: 49ms)
Something like Java in a single line
// String str = "hello";
// System.out.println(str + 'a');
const char *str = "hello";
printf("%s%c\n", str, 'a');
Or is one wants to print a concatenated string, we need to do memory management.
char *charcatconst char *src, int ch) {
size_t len = strlen(src);
char *s = memcpy(malloc(len+2), src, len); // Out-of-memory check omitted.
s[len] = ch;
s[len+1] = '\0';
return s;
}
// simple usage, but a memory leak
puts(charcat("hello", 'a'));
// Better to free memory explicitly
char *s = charcat("hello", 'a');
puts(s);
free(s);
I implement a simple strcpy, but when i run it , it always give a segmentation fault.
Please help!
Below is my code:
#include <stdio.h>
char* mystrcpy(char *dst, char *src){
char *ptr = dst;
while (*src !='\0') {
*dst = *src;
dst++;
src++;
}
return ptr;
}
int main (int argc, char **argv) {
char *str1 = "abc";
char *str2 = "def";
char *str3 = NULL;
str3 = mystrcpy(str2, str1);
printf("str2 now is %s", str2);
printf("str3 is %s", str3);
return 0;
}
These are read-only. Writing to them results in undefined behavior.
char *str1="abc"; /* Read-only. */
char *str2="def";
while (*src !='\0') {
*dst = *src; /* Writes into read-only memory. */
See this C FAQ:
String constants are in fact constant. The compiler may place them in
nonwritable storage, and it is therefore not safe to modify them.
And another explanation. You should try
char str1[]="abc";
char str2[]="def";
while( *src !='\0'){
*dst=*src;
You need to dereference your pointers here, using &, not *
EDIT:
Looks like I'm having my own personal cranial segmentation fault, here - too early in the morning!
cnicutar's explanation (assigning a pointer to a string constant with char *str2 = "def";, and then trying to write to that location) is much more plausible...