如何从字符串初始化char数组

时间:2009-06-08 08:37:29

标签: c

我想做以下

char a[] = { 'A', 'B', 'C', 'D'};

但我不想单独写这些字符。我想要像

这样的东西
#define S "ABCD"

char a[] = { S[0], S[1], S[2], S[3] };

但是这不会编译(gcc说'初始化元素不是常量')。

我尝试用

替换#define行
const char S[] = "ABCD";

但这似乎没有帮助。

我怎么能这样做(或类似的东西)让我把“ABCD”写成普通的'字符串',而不是作为四个单独的字符?

P.S。似乎人们没有正确地阅读这个问题......

我无法编译以下代码:

const char S[] = "ABCD";
char t[] = { S[0], S[1], S[2], S[3] };
char u[] = { S[3], S[2], S[1], S[0] };

11 个答案:

答案 0 :(得分:18)

你不能 - 在C中。在C中初始化全局和局部静态变量的设计使得编译器可以将值静态地放入可执行文件中。它不能将非常量表达式作为初始化器处理。并且只有在C99中,您可以在聚合初始化器中使用非常量表达式 - 在C89中不是这样!

在您的情况下,由于您的数组是包含字符的数组,因此每个元素必须是一个算术常量表达式。看看它说的那些

  

算术常量表达式应具有算术类型且仅具有   操作数是整数常量,浮点常量,枚举常量,字符   常量和sizeof表达式。

使用指针类型的操作数的初始化程序肯定不满足。当然,另一种方法是使用字符串文字初始化数组,因为它也解释

  

具有静态存储持续时间的对象的初始值设定项中的所有表达式都应为常量表达式或字符串文字。

所有报价均摘自C99 TC3委员会草案。总而言之,你想做的事情 - 使用非常量表达式 - 不能用C完成。你有几个选择:

  • 多次写你的东西 - 一次颠倒,另一次不反转。
  • 更改语言 - C ++可以做到这一切。
  • 如果确实想要这样做,请使用char const*数组

这就是我最后一个选项的意思

char const c[] = "ABCD";
char const *f[] = { &c[0], &c[1], &c[2], &c[3] };
char const *g[] = { &c[3], &c[2], &c[1], &c[0] };

这很好,因为地址常量表达式用于初始化指针

  

地址常量是空指针,指向静态存储持续时间对象的左值的指针,或指向函数指示符的指针;它应该使用一元& amp;运算符或整数常量强制转换为指针类型,或通过使用数组或函数类型的表达式隐式。 array-subscript []和member-access。和 - >运营商,地址&和间接*一元运算符和指针强制转换可用于创建地址常量,但不能使用这些运算符访问对象的值。

你可能有运气调整你的编译器选项 - 另一个引用:

  

实现可以接受其他形式的常量表达式。

答案 1 :(得分:5)

简单地

const char S[] = "ABCD";

应该有用。

你的编译器是什么?

答案 2 :(得分:3)

另一种选择是使用sprintf。

例如,

char buffer[50];
sprintf( buffer, "My String" );
祝你好运。

答案 3 :(得分:0)

这在gcc版本4.3.3(Ubuntu 4.3.3-5ubuntu4)上编译很好。

const char s[] = "cheese";

int main()
{
    return 0;
}

答案 4 :(得分:0)

const char S[] = "ABCD";

这应该有效。我只使用这种符号,它对我来说非常好。我不知道你是怎么用的。

答案 5 :(得分:0)

这是一个模糊的解决方案:定义宏功能:

#define Z(x) \
        (x==0 ? 'A' : \
        (x==1 ? 'B' : \
        (x==2 ? 'C' : '\0')))

char x[] = { Z(0), Z(1), Z(2) };

答案 6 :(得分:0)

奇怪的错误。

你能测试一下吗?

const char* const S = "ABCD";
char t[] = { S[0], S[1], S[2], S[3] };
char u[] = { S[3], S[2], S[1], S[0] };

答案 7 :(得分:0)

我不确定你的问题是什么,但以下似乎工作正常:

#include <stdio.h>

int main()
{
    const char s0[] = "ABCD";
    const char s1[] = { s0[3], s0[2], s0[1], s0[0], 0 };

    puts(s0);
    puts(s1);
    return 0;
}


Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
cl /Od /D "WIN32" /D "_CONSOLE" /Gm /EHsc /RTC1 /MLd /W3 /c /ZI /TC
   .\Tmp.c
Tmp.c
Linking...

Build Time 0:02


C:\Tmp>tmp.exe
ABCD
DCBA

C:\Tmp>

编辑2009年6月9日

如果您需要全局访问权限,可能需要这样的丑陋内容:

#include <stdio.h>

const char *GetString(int bMunged)
{
    static char s0[5] = "ABCD";
    static char s1[5];

    if (bMunged) {
        if (!s1[0])  {
            s1[0] = s0[3]; 
            s1[1] = s0[2];
            s1[2] = s0[1];
            s1[3] = s0[0];
            s1[4] = 0;
        }
        return s1;
    } else {
        return s0;
    }
}

#define S0 GetString(0)
#define S1 GetString(1)

int main()
{
    puts(S0);
    puts(S1);
    return 0;
}

答案 8 :(得分:0)

如果三个变量是全局的,那么编译问题只适用于我(gcc 4.3,ubuntu 8.10)。问题是C不像脚本语言那样工作,所以你不能理所当然地认为u和t的初始化发生在s之后。这就是你得到编译错误的原因。现在,你无法以之前的方式初始化t和y,这就是为什么你需要一个char *。执行此工作的代码如下:

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

#define STR "ABCD"

const char s[] = STR;
char* t;
char* u;

void init(){
    t = malloc(sizeof(STR)-1);
    t[0] = s[0];
    t[1] = s[1];
    t[2] = s[2];
    t[3] = s[3];


    u = malloc(sizeof(STR)-1);
    u[0] = s[3];
    u[1] = s[2];
    u[2] = s[1];
    u[3] = s[0];
}

int main(void) {
    init();
    puts(t);
    puts(u);

    return EXIT_SUCCESS;
}

答案 9 :(得分:0)

在这种情况下,生成适当代码的脚本可能有所帮助。

答案 10 :(得分:-1)

也许你的角色阵列需要保持不变。由于您使用常量字符串中的字符初始化数组,因此您的数组必须是常量。试试这个:

#define S "ABCD"
const char a[] = { S[0], S[1], S[2], S[3] };