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#?
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.
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.
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).
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.
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):
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With