简体   繁体   中英

C char of string to array

I have 2 defines, one with a string and one with a number.How can i make a const array from the define with the string and the number. There are also some additional constant which should be in this array.

How can i write this Code to have 0x22, 0x41, 0x42, 0x42, 0x21 in the array foobar, from the defines FOO and BAR?

#define FOO "AB"
#define BAR 33

extern int rs232_write(const unsigned char *data, unsigned char count);

const unsigned char foobar[] =
{
    0x22,
    FOO[0], /*what must i put here, this do not work*/
    FOO[1],
    0x42,
    BAR,
};


int main(void)
{
    rs232_write(foobar,sizeof(foobar));
    return 1;
}

In gcc, for example, i get the error:

./001.c:9:5: error: initializer element is not constant
     FOO[0], /*what must i put here*/
     ^

The String have always the same length. I did also a try the other way around:

#define FOO "AB"
#define BAR 33

extern int rs232_write(const unsigned char *data, unsigned char count);

const char foobar[] = \
    "\x22" \
    FOO    \
    "\x42" \
    BAR   /*what must i put here, this also not work*/


int main(void)
{
    rs232_write(foobar,sizeof(foobar));
    return 1;
}

Here i get also a error, for example gcc prints:

./002.c:2:13: error: expected ‘,’ or ‘;’ before numeric constant
 #define BAR 33
             ^

I working on a Microcontroller with not much space, so i would like to avoid creating the array at runtime and my compiler do only support C89.

This should work:

#include<stdio.h>

#define FOO 'A','B'
#define BAR 33

const char foobar[] = {
    0x22,
    FOO,
    0x42,
    BAR,  
    '\0'
};

int main(void)
{
    printf("%s\n", foobar);
    return 0;
}

BTW it is very bad to init the array that way, maybe you can explain your aim better.

#include <stdio.h>
#include <stdlib.h>

#define FOO           "ab"
#define BAR           33

#define STRINGIFY(x)  STRINGIFY2(x)
#define STRINGIFY2(x) #x

const char foobar[] = "\x22" FOO "\x42" STRINGIFY(BAR);

int main(void)
{
  printf("foobar = |%s| (%ld+1 characters)\n",
    foobar, (long) sizeof(foobar) - 1);
  return EXIT_SUCCESS;
}

Running this program ouputs:

foobar = |"abB33| (6+1 characters)

The simplest, using memcpy :

#include <stdio.h>
#include <string.h>

#define FOO "AB"
#define BAR 33

extern int rs232_write(const unsigned char *data, unsigned char count);

unsigned char _foobar[] =
{
    0x22,
    0, 0,
    0x42,
    BAR,
};
const unsigned char *foobar;

int main(void)
{
    foobar = (const unsigned char *)memcpy(_foobar + 1, FOO, 2) - 1;
    rs232_write(foobar,sizeof(foobar));
    return 0;
}

The ugly, using an X Macro and a compound literal :

In this way you can use the first two digits:

const unsigned char foobar[] =
{
    0x22,
    'A', 'B',
    0x42,
    33,
};

or the full string "AB"

#include <stdio.h>

#define FOO X('A', 'B', '\0')
#define BAR 33

extern int rs232_write(const unsigned char *data, unsigned char count);

const unsigned char foobar[] =
{
    0x22,
    #define X(a, b, c) a, b
    FOO,
    #undef X
    #define X(a, b, c) ((char []){a, b, c})
    0x42,
    BAR,
};

int main(void)
{
//  rs232_write(foobar,sizeof(foobar));
    printf("%s\n", FOO);
    return 0;
}

Output:

AB

The problem is that the compiler doesn't know, at the time of compilation, where the string literal "AB" will be placed in memory. Its location will be decided when the program is linked or possibly when it is loaded into memory.

Therefore using it will not result in a compile-time constant that is required for the initialization of the foobar array.

In this case you really have no option but to use setting foobar[1] and foobar[2] once at run-time. However, even on an extremely small embedded system this will not incur much overhead either in memory or in time. If the program runs more than a few seconds it will most likely not even be measurable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM