字符串到数组的C char

时间:2017-01-30 12:25:19

标签: c arrays c-preprocessor const c89

我有2个定义,一个带字符串,另一个带数字。如何使用字符串和数字从定义中创建一个const数组。还有一些额外的常量应该在这个数组中。

如何编写此代码,使数组foobar中的0x22,0x41,0x42,0x42,0x21来自定义FOO和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;
}

例如,在gcc中,我收到错误:

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

String的长度始终相同。 我也尝试了另一种方式:

#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;
}

这里我也遇到了错误,例如gcc prints:

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

我在没有太多空间的微控制器上工作,所以我想避免在运行时创建数组,而我的编译器只支持C89。

4 个答案:

答案 0 :(得分:1)

这应该有效:

#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;
}
顺便说一句,以这种方式初始化阵列是非常糟糕的,也许你可以更好地解释你的目标。

答案 1 :(得分:1)

#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;
}

运行此程序输出:

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

答案 2 :(得分:1)

最简单,使用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;
}

丑陋,使用X Macrocompound literal

通过这种方式,您可以使用前两位数字:

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

或完整字符串"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;
}

输出:

AB

答案 3 :(得分:0)

问题是编译器在编译时不知道字符串文字"AB"将放在内存中的位置。它的位置将在程序链接时或者可能在加载到内存时确定。

因此,使用它不会导致foobar数组初始化所需的编译时常量。

在这种情况下,您真的别无选择,只能在运行时使用foobar[1]foobar[2]设置。然而,即使在极小的嵌入式系统上,这也不会在内存或时间上产生太多开销。如果程序运行超过几秒钟,则很可能甚至无法测量。