As has been pointed out, the direct problem is that you're trying to call sprintf
from outside a function.
You mentioned that you are setting the strings this way because you're using SITE_NAME
by itself in addition to concatenating it with the path and you want to only have to change it in one place. This is a good goal, known in some circles as "don't repeat yourself" (often abbreviated DRY). However, even if the code worked (say, because you moved the sprintf
call into main), you haven't really achieved your goal due to the following line:
char SITE_ROOT[19];
You are declaring a fixed length array exactly big enough to hold "/var/www/html/test"
, which is just asking for a buffer overflow. When you change SITE_NAME
from "test"
to, for example, "someRealSiteName"
, you'll very probably overwrite something else when you concatenate, causing unpredictable results. So you have to manually recalculate the length of the final string and update the array size (which would be easy to get wrong, say by forgetting to add 1 for the null terminator) every time you change SITE_NAME
.
You could, of course, limit the length of SITE_NAME
and size SITE_ROOT
to hold the longest possible path, but it'd be an artificial limit and you might end up wasting space. Furthermore, you'd still have to verify the length isn't exceeded at run-time (or use a function that will ignore extra characters).
Instead, you could dynamically set the size of SITE_ROOT
like so:
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
const char SITE_PATH[] = "/var/www/html/";
const char SITE_NAME[] = "someRealSiteName";
char *SITE_ROOT = NULL; // just making this explicit, would be set to 0 anyway
int main(void)
{
size_t siteRootLength = strlen(SITE_PATH) + strlen(SITE_NAME);
SITE_ROOT = malloc(siteRootLength + 1); //don't forget to account for the terminating '\0'
strcpy(SITE_ROOT, SITE_PATH);
strcat(SITE_ROOT, SITE_NAME);
printf("%s\n", SITE_NAME):
printf("%s\n", SITE_PATH):
printf("%s\n", SITE_ROOT):
return 0;
}
This solution is okay, but has some drawbacks:
SITE_ROOT
can't be a const
pointer , so both the string and the pointer itself could be accidentally changed
- Site path and name will each be in memory twice (though it sounds like you're okay with that)
- Concatenation is being done at run-time when it could be done at compile-time
- Code is longer and more complex than necessary for such a simple task
- Risk that
SITE_ROOT
is used before it has the correct value (or is even a valid pointer/string!) in some other initialization code or another thread.
I feel something like the following is better:
#include <stdio.h>
#define SITE_PATH_MACRO "/var/www/html/"
#define SITE_NAME_MACRO "someRealSiteName"
// the preprocessor will merge the two string literals into one
#define SITE_ROOT_MACRO SITE_PATH_MACRO SITE_NAME_MACRO
// you could do without some or all of these if you don't need them
// (or are willing to use the macros directly)
const char SITE_PATH[] = SITE_PATH_MACRO;
const char SITE_NAME[] = SITE_NAME_MACRO;
const char SITE_ROOT[] = SITE_ROOT_MACRO;
int main(void)
{
printf("%s\n", SITE_NAME);
printf("%s\n", SITE_PATH);
printf("%s\n", SITE_ROOT);
return 0;
}