Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using strcat in C

Tags:

c

string

Okay so I have the following Code which appends a string to another in C#, note that this is Just an example, so giving alternative string concatination methods in C# is not nessesary, this is just to simplify the example.

string Data = "";
Data +="\n\nHTTP/1.1 " + Status_code;
Data += "\nContent-Type: " + Content_Type;
Data += "\nServer: PT06";
Data += "\nContent-Length: " + Content_Lengt;
Data += "\nDate: " + Date;
Data += "\n" + HTML;

Now I'd like to do the exact same thing in C and I'm trying to do this the following way

time_t rawtime;

time ( &rawtime );

char *message = "\n\nHTTP/1.1 ";
message = strcat(message, Status_code);
message = strcat(message, "\nContent-Type: ");
message = strcat(message, Content_Type);
message = strcat(message, "\nServer: PT06");
message = strcat(message, "\nContent-Length: ");
message = strcat(message, Content_Lengt);
message = strcat(message,  "\nDate: ");
message = strcat(message, ctime(&rawtime));
message = strcat(message, "\n");
message = strcat(message, HTML);

Now, this gives me a Segment fault, I know why, I access and read on memory that i shouldn't. But the question is, how do i solve it? Could I use string.h and just do it the same way that I did in C#?

like image 621
Filip Ekberg Avatar asked Jan 07 '09 08:01

Filip Ekberg


People also ask

What is the use of strcat () function in C?

The strcat() function concatenates string2 to string1 and ends the resulting string with the null character. The strcat() function operates on null-ended strings. The string arguments to the function should contain a null character (\0) that marks the end of the string. No length checking is performed.

Can we use strcat in C?

In C/C++, strcat() is a predefined function used for string handling, under string library (string. h in C, and cstring in C++). This function appends the string pointed to by src to the end of the string pointed to by dest. It will append a copy of the source string in the destination string.

What is the use of strcat () and Strcon () function?

Explanation: The strcat() function is used for concatenating two strings, appends a copy of the string. 3. The ______ function appends not more than n characters. Explanation: The strncat() function appends not more than n characters from the array(s2) to the end of the string(s1).

What is the correct syntax for strcat in C?

This syntax of the strcat() function is: Syntax: char* strcat (char* strg1, const char* strg2); This function is used to concatenate two strings. This function accepts two arguments of type pointer to char or (char*) , so you can either pass a string literal or an array of characters.


2 Answers

Change

char *message = "\n\nHTTP/1.1 ";

to

char message[1024];  
strcpy(message,"\n\nHTTP/1.1 ");

and you should be ok, up to a total message length of 1023.

Edit: (as per mjy's comment). Using strcat in this fashion is a great way of getting buffer overflows. You could readily write a small function that checks the size of the buffer and length of incoming string addition to overcome this, or use realloc on a dynamic buffer. IMO, the onus is on the programmer to check correct buffer sizes where they are used, as with sprintfs and other C strings functions. I assume that C is being used over C++ for performance reasons, and hence STL is not an option.

Edit: As per request from Filip's comment, a simple strcat implementation based on a fixed size char buffer:

char buffer[MAXSIZE] = "";

int mystrcat(char *addition)
{
   if (strlen(buffer) + strlen(addition) + sizeof(char)  >= MaxSize)
     return(FAILED);
   strcat(buffer,addition);
   return(OK);
}

Using dynamic allocation:

char *buffer = NULL;

int mystrcat(char *addition)
{
   buffer = realloc(buffer, strlen(buffer) + strlen(addition) + sizeof(char));
   if (!buffer)
     return(FAIL);
   strcat(buffer, addition);
   return(OK);
}

In this case you have to free your buffer manually when you are finished with it. (Handled by destructors in C++ equivalents)

Addendum (Pax):

Okay, since you didn't actually explain why you had to create message[1024], here it is.

With char *x = "hello", the actual bytes ('h','e','l','l','o',0) (null on the end) are stored in an area of memory separate from the variables (and quite possibly read-only) and the variable x is set to point to it. After the null, there's probably something else very important. So you can't append to that at all.

With char x[1024]; strcpy(x,"hello");, you first allocate 1K om memory which is totally dedicated to x. Then you copy "hello" into it, and still leave quite a bit of space at the end for appending more strings. You won't get into trouble until you append more than the 1K-odd allowed.

End addendum (Pax):

like image 168
SmacL Avatar answered Oct 27 '22 13:10

SmacL


I wonder why no one mentioned snprintf() from stdio.h yet. That's the C way to output multiple values and you won't even have to convert your primitives to strings beforehand.

The following example uses a stack allocated fixed-sized buffer. Otherwise, you have to malloc() the buffer (and store its size), which would make it possible to realloc() on overflow...

char buffer[1024];
int len = snprintf(buffer, sizeof(buffer), "%s %i", "a string", 5);
if(len < 0 || len >= sizeof(buffer))
{
    // buffer too small or error
}

Edit: You might also consider using the asprintf() function. It's a widely available GNU extension and part of TR 24731-2 (which means it might make it into the next C standard). The example from above would read

char * buffer;
if(asprintf(&buffer, "%s %i", "a string", 5) < 0)
{
    // (allocation?) error
}

Remember to free() the buffer when done using it!

like image 39
Christoph Avatar answered Oct 27 '22 12:10

Christoph