我尝试编写一个从键盘上读取单个符号的程序。如果它们尚未存在,则应存储在数组中。
之后,所有标志都会被排序,并且所有已经出现的标志都会打印出来。
编辑:如果输入的符号已经存在,则不会添加。该数组应该只包含唯一的元素。
数组的大小为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();
}
答案 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;
功能
以下是更正后的版本:
main