在C中编写/分配字符串列表



我正在用C语言制作一个字符串列表,我在网上找不到任何可以轻松添加和清除字符串列表的东西。这将接近Perl的"push"函数。

我想在这里分享我想到的代码:

#include <stdio.h>//printf
#include <stdlib.h>//EXIT_FAILURE, malloc, realloc
#include <string.h>//need for strcmp and strlen
void *add_name(char **restrict array, size_t *restrict size, size_t *restrict number_of_names, const char *restrict NAME) {//this function works, when freed inside main()
    for (unsigned int name = *number_of_names-1; name <= 0; name--) {
        if (strcmp(array[name], NAME) == 0) {
            return array;//if this name is already in the list, don't add it
        }
    }
    const size_t NAME_SIZE = strlen(NAME)*sizeof(char)+sizeof(char*);
    *size += NAME_SIZE;
    array = realloc(array, *size);
    if (array == NULL) {
        puts("realloc of array failed.n");
        exit(EXIT_FAILURE);
    }
    array[*number_of_names] = malloc(NAME_SIZE);
    if (array[*number_of_names] == NULL) {
        printf("alloc of array[%zu] failed.n", *number_of_names);
        exit(EXIT_FAILURE);
    }
    strcpy(array[*number_of_names], NAME);
    *number_of_names += 1;
    return array;
}
void *clear_names(char **restrict array, size_t *restrict size, size_t *restrict number_of_names) {//empty the list of names
    for (size_t name = 0; name < *number_of_names; name++) {
        free(array[name]); array[name] = NULL;//this is missing something
        if (array[name] != NULL) {
            printf("free of array[%zu] failed.n", name);
        }
    }
    *number_of_names = 0;
    *size = sizeof(char);
    array = realloc(array, *size);
    if (array == NULL) {
        printf("realloc of array failed @ line %un",__LINE__);
        exit(EXIT_FAILURE);
    }
    return array;
}
int main (void) {
    puts("This program demonstrates how to add to and clear a list of names.");
    size_t name_list_size = sizeof(char);
    char **name_list = malloc(name_list_size);
    size_t number_of_names = 0;
    name_list = add_name(name_list, &name_list_size, &number_of_names, "James");
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Mary");
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Mary");
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Thomas");
    for (size_t name = 0; name < number_of_names; name++) {
        printf("%sn",name_list[name]);
    }
    name_list = clear_names(name_list, &name_list_size, &number_of_names);
//
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Matthew");
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Mark");
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Luke");
    name_list = add_name(name_list, &name_list_size, &number_of_names, "John");
    for (size_t name = 0; name < number_of_names; name++) {
        printf("%sn",name_list[name]);
    }
//
    name_list = clear_names(name_list, &name_list_size, &number_of_names);
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Titus");
    printf("size = %zu  number_of_names = %zun", name_list_size, number_of_names);
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Peter");
    printf("size = %zu  number_of_names = %zun", name_list_size, number_of_names);
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Bartholomew");
    printf("size = %zu  number_of_names = %zun", name_list_size, number_of_names);
    name_list = add_name(name_list, &name_list_size, &number_of_names, "Paul");
    printf("size = %zu  number_of_names = %zun", name_list_size, number_of_names);
    for (size_t name = 0; name < number_of_names; name++) {
        printf("%sn",name_list[name]);
    }
    name_list = clear_names(name_list, &name_list_size, &number_of_names);
    free(name_list); name_list = NULL;
    return 0;
}

我的建议如下:

  • realloc分配给临时指针,因此如果它返回NULL,您不会销毁array
  • 使用strdup代替malloc作为字符串存储
  • 使用lsearch检查&插入字符串
  • 当增加array的大小时,通过加倍而不是线性进行
  • 打包数组,它的计数&struct(见下文)中的容量,并将其作为参数传递给add &明确功能

您需要添加一个比较函数以传递给lsearch。如果lsearch添加了一个名称,它将更新计数。分配仍然取决于您,因此在调用它之前请确保容量超过计数。

如果你这样做,我想你会发现你的代码更小,更简单。它还可以添加delete &搜索功能。

使用结构体的一个优点是可以使用较短的名称,例如:

struct name_list_t { 
       char **array; 
       size_t n, capacity; } names = { .array = NULL };

//当在main()中释放时,该函数有效

咩。这个注释实际上没有意义,因为函数没有被释放。我明白你的意思,但你在逼我工作。

HTH。

相关内容

  • 没有找到相关文章

最新更新