Dynamically construct a char in C

2019-04-15 13:42发布

问题:

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

回答1:

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.



回答2:

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



回答3:

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.



标签: c string strcpy