字符串的 C char 到数组

C char of string to array

我有 2 个定义,一个带有字符串,一个带有 number.How 我可以使用字符串和数字从定义中创建一个 const 数组吗?还有一些额外的常量应该在这个数组中。

我如何根据定义的 FOO 和 BAR 编写此代码以在数组 foobar 中包含 0x22、0x41、0x42、0x42、0x21?

#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*/
     ^

字符串的长度始终相同。 我也尝试了另一种方法:

#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 打印:

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

我在微控制器上工作 space,所以我想避免在运行时创建数组,我的编译器只支持 C89。

这应该有效:

#include<stdio.h>

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

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

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

顺便说一句,这样初始化数组是非常糟糕的,也许你可以更好地解释你的目标。

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

因此使用它不会产生初始化 foobar 数组所需的 compile-time 常量。

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

#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)

最简单,使用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 Macro and a compound literal

这样就可以使用前两位了:

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

或完整字符串 "AB"

#include <stdio.h>

#define FOO X('A', 'B', '[=12=]')
#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