我知道问题看起来很奇怪,但我需要在C中初始化(或转换)一个常量字符串数组。
问题是字符串数组是动态初始化的,但是我想使用的API函数只接受常量字符串数组。
我知道这有效:
const char *const arr[] = { "test" };
但是再说一遍:既然我不知道数组会有多少项,也不知道运行前的内容,我就无法通过这种方式初始化数组。
当然,这不会起作用
const char *const arr[1];
arr[1] = "test"; // won't work
我的问题是:是否有可能将动态字符串数组以某种方式转换为只读数组?或者有一种方法可以动态初始化数组吗?
编辑1:我的确切问题
int len = 8;
const char *names1[8] = {"test0","test1","test2","test3","test4","test5","test6","test7" }; // not what I'm looking for
const char *names2[len];
const char *names3[len];
// nearly what I'm looking for
for(int j=0; j<len; j++) {
names2[j] = "test";
}
// exactly what I'm looking for
for(int j=0; j<len; j++) {
sprintf(names3[j],"%s%d","test",j); // discards 'const' qualifier
}
// ...
Cudd_DumpDot(gbm, 1, ddnodearray, names1, NULL, outfile);
Cudd_DumpDot(gbm, 1, ddnodearray, names2, NULL, outfile);
Cudd_DumpDot(gbm, 1, ddnodearray, names3, NULL, outfile); // won't work
好的,这是我目前的进展。
使用names2
的方法确实有效,但我想使用sprintf
(如names3
所示),因为在这种情况下我需要附加j
。这会伤害const
限定符。
答案 0 :(得分:3)
从技术上讲,没有什么可以阻止你将指针转换为(char *
),然后使用memset
或类似设置元素。
然而,这会调用未定义的行为,因为编译器可以将它放入只读标记的内存中。
Excerpt from an answer on another SO question:
const限定符是编译器拒绝代码的指令 尝试直接修改该对象;试图修改 间接对象(正如您在第二个代码片段中所做的那样)导致 未定义的行为,意味着任何结果都是可能的。
在初始化之后无法(不调用UB)更改常量 - 所以不要这样做。
UPDATE 正如@chux在评论中指出的那样,确实可以动态初始化局部变量。
答案 1 :(得分:2)
我想使用的API函数只接受常量字符串数组。
没有理由传递常量指针数组......允许转换为<myComplexArg>foo=bar,bas=1|x=y,z=2</myComplexArg>
(在本例中为常量数组元素)(甚至是隐式),因此以下(无意义)代码编译得很好:
const
答案 2 :(得分:1)
动态初始化一个常量字符串数组
在函数中,有多种方法可以在运行时初始化const
字符串数组。
// example
const char *s[2] = { (char [3]){ rand(), 0, 0},(char [3]){ rand(), 0, 0} };
然而,OP似乎只需要类似的东西。
形成各种字符串,每个字符串都在有效的内存中。
// Exmaple
#define SZ (4 + 11 + 1)
char buf[len][SZ];
for(int j=0; j<len; j++) {
sprintf(buf[j],"%s%d","test",j);
}
形成一个const char *
const char *names[len];
for(int j=0; j<len; j++) {
names[len] = buf[len];
}
致电Cudd_DumpBlifBody()
。可以使用char const *const *
或char const *const *
char const **
参数
#include <stdio.h>
#include <stdlib.h>
typedef void DdManager;
typedef void DdNode;
int Cudd_DumpBlifBody(DdManager *dd, int n, DdNode **f,
char const *const *inames,
char const *const *onames, FILE *fp, int mv) {
return 0;
}
#define SZ (4 + 11 + 1)
int sw(int len) {
char buf[len][SZ];
const char *names[len];
for(int j=0; j<len; j++) {
sprintf(buf[j],"%s%d","test",j);
names[len] = buf[len];
}
char const *const *inames = names;
char const *const *onames = names;
return Cudd_DumpBlifBody (NULL, 0, NULL, inames, onames, NULL, 0);
}
像char buf[len][SZ];
这样的本地对象很容易变得太大而无法进行本地存储。如果不确定或*alloc()
可能很大,请考虑len
。