I am trying to construct an array that has a series of character that I want to construct in the fly, the characters are like this \x01
, \x02
and so on.
For example, lets say we have:
#define NUMCOLORS 3
char delim[NUMCOLORS];
And we want to have in delim
the values \x01, \x02, \x03
.
I thought two possible ways to do it, but both cause a segfault:
for (int i = 0; i < NUMCOLORS; i++){
char *h = "\x01";
sprintf(h, "\x0%d", i+1);
strcpy(delim[i], h);
}
// Other way
for (int i = 0; i < NUMCOLORS; i++){
char *h = "\x0";
strcpy(delim[i], h+1);
}
Is there a way I can create the char
I need
No, don't use strcpy
as it will add the string terminator. Also, doing h + 1
give you the next character in the string pointed to by h
which is the string terminator.
Instead use the fact that a character is actually an integer value. That means you can do e.g.
char delim[4];
for (int i = 0; i < 3; ++i)
delim[i] = i + 1;
/* Terminates as string */
delim[3] = '\0';
Now you can use delim
as any other string in C, and contain the string "\01\02\03"
.
If you want the string to contain not the characters '\01'
, '\02'
etc, then you need a bigger array, and another way of constructing the string:
/* 3 sequences of 4 characters (backslash, x, two digits), plus terminator */
char delims[3 * 4 + 1] = { 0 }; /* Initialize to zero (the string terminator) */
for (int i = 0; i < 3; ++i)
{
char temp[5]; /* Place for 4 characters plus terminator */
sprintf(temp, "\\x%02d", i);
strcat(delims, temp);
}
Now after this the string delims
will contain the string "\x01\x02\x03"
. Note that the backslashes are real backslashes, not something that the compiler will translate, if you print the string to the console the output will be exactly that, backslashes an all.
char *h = "\x01"; ( will place \x01 in the read-only parts of the memory )
sprintf(h, "\x0%d", i+1); // not valid
this is pointer pointed to constant string. it's illegal to modify it. Read this my answer
The notation "\x01"
is a way to tell the compiler "When you create the constant to represent this string literal, replace me with the character with the numeric value 1
." The backslash (and x
) does not even make it into the compiled module. If you want a character of a certain (dynamic) numeric value in a string, simply append that numeric value (cast to char
) to the string. Joachim gives you some ideas.
The "\x01"
notation is just a "convenience" when you have some fixed numeric value you wish to insert into a string literal.