使用动态数组

时间:2018-06-14 19:47:36

标签: c

我尝试编写一个从键盘上读取单个符号的程序。如果它们尚未存在,则应存储在数组中。

之后,所有标志都会被排序,并且所有已经出现的标志都会打印出来。

编辑:如果输入的符号已经存在,则不会添加。该数组应该只包含唯一的元素。

数组的大小为0,每当新字符到达时,它的容量应加倍。

不幸的是它似乎无法正常工作。如果我通过调试器查看,看起来这些值会一个接一个地存储,但是一旦第二个符号到达,程序就会在print / qsort中崩溃。

我在分配方面做错了吗?

如果您有其他改进此代码的建议,请告知我们。

#include <stdio.h>
#include <stdlib.h>

void reserve_space(char **c, int *capacity);
void print_signs(char **signs, const int max_size);
int cmp(void const *lhs, void const *rhs);

// allocates factor 2 of the current capacity
void reserve_space(char **c, int *capacity) {
    char *new_c;

    if (*capacity == 0) {       // allocate the first time
        *capacity = 1;
        *c = malloc(sizeof(char) * ((*capacity)));
    } else {
        *capacity *= 2;     // double the new capacity
        new_c = realloc(*c, sizeof(char) * (*capacity));
        *c = new_c;
    }
    return;
}

void print_signs(char **signs, const int sz) {
    int i = 0;

    for (i = 0; i < sz; ++i) {
        printf("%i %c\n", *signs[i], *signs[i]);            // crash in read after array has 2 signs???
    }
    printf("\n");
}

int cmp(void const *lhs, void const *rhs) {
    char left = *((char *)lhs);
    char right = *((char *)rhs);

    if (left < right) return -1;
    if (left > right) return  1;

    return 0;  /* left == right */
}

int main() {
    int capacity = 0;       // allocated space 
    int sz = 0;             // space currently "filled" with signs
    char *signs = 0;

    char ch = 0;
    int pos = 0;

    while ((ch = getc(stdin)) != EOF) {
        int pos = 0;

        if (sz == capacity)
            reserve_space(&signs, &capacity);

        for (pos = 0; pos < sz; ++pos) {
            if (signs[pos] == ch)
                continue;   /* indicating element exists already */
        }

        if (pos == capacity - 1)    // -1 because last sign must be terminating '\0'
            reserve_space(&signs, &capacity);

        signs[pos] = ch;    //adding new sign at pos of "old" \0
        ++sz;
        ++pos;
        signs[pos] = '\0';  //adding new terminating \0

        qsort(&signs, sz - 1, sizeof(char), cmp);

        print_signs(&signs, sz);
    }
    getchar();
}

1 个答案:

答案 0 :(得分:3)

print_sign中存在一个错误:*[]之间的优先顺序是*signs[i]被解析为*(signs[i])而不是{{} 1}}如你所愿。

以下是更正后的版本:

(*signs)[i]

实际上没有理由将指针的地址传递给此函数。它可以简化为:

void print_signs(char **signs, const int sz) {
    int i = 0;

    for (i = 0; i < sz; ++i) {
        printf("%i %c\n", (*signs)[i], (*signs)[i]);
    }
    printf("\n");
}

并称为void print_signs(char *signs, const int sz) { int i = 0; for (i = 0; i < sz; ++i) { printf("%i %c\n", signs[i], signs[i]); } printf("\n"); }

您的代码中还有许多其他问题:

  • print_signs(signs, sz);应定义为ch
  • 查找循环中的int语句没有实际意义,您应该将循环写为

    continue
  • 如果for (pos = 0; pos < sz; ++pos) { if (signs[pos] != ch) break; /* indicating element exists already */ } if (pos < sz) continue; 功能

  • ,其余的则会有1个错误
  • 比较功能也被破坏了。

以下是更正后的版本:

main