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

我想做以下事情

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”写成普通的’字符串’,而不是四个单独的字符?

PS似乎人们没有正确地阅读这个问题……

我无法编译以下代码:

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

你不能 – 在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] }; 

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

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

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

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

只是

 const char S[] = "ABCD"; 

应该管用。

什么是你的编译器?

另一种选择是使用sprintf。

例如,

 char buffer[50]; sprintf( buffer, "My String" ); 

祝好运。

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

 const char s[] = "cheese"; int main() { return 0; } 
 const char S[] = "ABCD"; 

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

奇怪的错误。

你能测试一下吗?

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

这是一个不起眼的解决方案:定义宏function:

 #define Z(x) \ (x==0 ? 'A' : \ (x==1 ? 'B' : \ (x==2 ? 'C' : '\0'))) char x[] = { Z(0), Z(1), Z(2) }; 

这是生成适当代码的脚本可能有用的一种情况。

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

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

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

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

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

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