C:动态初始化一个常量字符串数组

时间:2017-10-19 15:56:36

标签: c arrays string

我知道问题看起来很奇怪,但我需要在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限定符。

3 个答案:

答案 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