-1

我需要对 C 中的长字符串列表执行各种功能。

char *list1[] = {"one","two","three", "four","five","six"};

最初,我正在尝试实现简单的 car/cdr 函数,但是已经有一段时间了,我忘记了在 C 中管理 char *[] 列表的最佳方法。 cdr 应该返回 char * 列表的其余部分在一个新的 malloc'ed 数组中。就我而言,它是“二”、“三”、“四”、“五”、“六”。未知的列表大小使这一点复杂化。也许,我应该使用具有列表长度的结构?

char **cdr(char *aList[]) {
  /*
   malloc space for n-1 char*
  */
  return aList; // Return everything to test
}

我将有其他功能,例如,返回具有两个连续元音的所有单词的列表,或者超过 10 个字符的单词。我永远不想更改字符串(即它们是不可变的)。我将在 cdr 之类的函数中分配内存,因此在获取结果并将它们传递给其他函数时,我需要跟踪它。无论如何,如果有人能让我开始,将不胜感激。谢谢。

char *list1[] = {"one","two","three", "four","five","six"}; // Short list

char **cdr(char *aList[]) {
  /*
   malloc space for n-1 char*
  */
  return aList; // Return everything to test
}

char *car(char *aList[]) {
  return aList[0];
}

int main() {
  const char *first;
  char *rest[];

  int len = sizeof(list1)/sizeof(char*);
  printf("list1 len=%d\n", len);

  first = car(list1);
  rest = cdr(list1);

  printf("%s\n", first);
  len = sizeof(rest)/sizeof(char*);
  printf("rest len=%d\n", len);

  return 0;
}
4

3 回答 3

2

列表大小未知与其说“复杂化”不如说“使它不可能”。如果您不想传递显式长度,则需要使用 NULL 值作为终止符。

int length(const char* strings[]) {
    int rv = 0;
    while( strings[rv] ) ++rv;
    return rv;
}

int main(int argc, char *argv[]) {
    printf( "Note that this technique is also used in argv: %p\n", argv[argc] );

    const *list[] = { "+", "42", "30", NULL };
    printf( "Length: %d\n", length( list ) );

    return 0;
}

在您的其他函数中使用这样的长度(),您应该能够知道要分配的适当内存量。(请记住,您需要为 NULL 的额外指针分配空间!)

于 2013-03-26T23:10:00.697 回答
2

通常,您要查找的列表不是作为数组实现的,而是作为链表实现的。它们最初实现的方式甚至是这些操作被称为“car”和“cdr”的原因(参见:http ://en.wikipedia.org/wiki/CAR_and_CDR )。

以这种方式实现的列表仅由包含两个指针的元素组成。因此,对于您的示例,这样的列表如下所示:

 +-----+-----+    +-----+-----+    +-----+-----+         +-----+-----+   
 | car | cdr | -> | car | cdr | -> | car | cdr | -> .... | car | cdr | -> NIL
 +-----+-----+    +-----+-----+    +-----+-----+         +-----+-----+
   |                 |                |                     |
   v                 v                v                     v
 "one"             "two"            "three"               "six"

为了在 C 中达到相同的效果,您宁愿对列表的元素使用如下结构:

struct _Element {
  struct _Element *cdr;
  void  *car;
};

如果您仍想继续使用数组方法,最好查看“svk”的帖子。使用 NULL 终止的数组而不是单独跟踪长度可能是您建议的版本的有趣替代方案。

于 2013-03-26T23:10:05.123 回答
0

C 中的所有分配和释放都是浪费和容易出错的。为什么不只返回实际的字符串?

char * car (char ** list) {
    return list[0];
}

char ** cdr (char ** list) {
    return list + 1;
}
于 2013-03-27T13:27:34.550 回答