C通用打印数组功能 - 打印字符串数组

时间:2017-01-23 08:56:29

标签: c arrays string generics printing

我正在尝试在C中编写通用打印数组函数,并且它在某种程度上对String数组不起作用。 这是主要的:

#define LEN 20

typedef struct {
    char name[LEN]; // worker's name
    int salary; // worker's salary
    char **childArr; // array of children names
    int numChildren; // number of children
} Worker;

void printArray(void* arr, int size, int typeSize,  void (*print)(void*));
void printString(void* s);
void printWorker(void* worker);

void main() {
    // arrays of children's names
    char *chBamba[] = { "Bambale1", "Bamb2", "Bamb3", "Bambook4", "Bambookle5" };
    char *chBisli[] = { "Bislile1", "Bischick2", "Bislile3", "Bis4"};
    int nBamba = sizeof(chBamba) / sizeof(*chBamba);
    int nBisli = sizeof(chBisli) / sizeof(*chBisli);

    // array of workers
    Worker a[] = { {"Printf", 10, NULL, 0}, {"Bisli", 20, chBisli, nBisli},
{"TapooChips", 3, chBamba, nBamba}, {"Bamba", 19, chBamba, nBamba} };

    printArray(a, sizeof(a)/sizeof(Worker), sizeof(Worker), printWorker);

}

功能:

void printArray(void* arr, int size, int typeSize,  void (*print)(void*)) {
    int i;
    for (i = 0; i < size; i++) {
        print((char*)arr+i *typeSize);
    }
    printf("\n");
}

void printString(void* s) {
    char* str = (char*)s;
    printf("[ %s ]", *str);
}

void printWorker(void* worker) {
    Worker* w = (Worker*)worker;
    printf("%s\t %d...(%d) ", w->name, w->salary, w->numChildren);
    if (w->numChildren != 0)
        printArray(w->childArr, w->numChildren, LEN, printString);

    printf("\n");
}

打印第二个工作人员的数据并转到“children”数组后,代码中断...

任何想法为什么?我该如何解决?

编辑后:printArray(w->childArr,w->numChildren,sizeof(w->childArr[0]),printString);

并且:printf("[ %s ]",str);

我现在有以下印刷品: img1

2 个答案:

答案 0 :(得分:1)

这一行:

LEN

您传递printArray作为数组中元素的大小,这可能比数组元素的大小大。这使得sizeof(char*)中的循环超出了数组边界,任何访问都是未定义的行为。

您的数组包含指向字符串的指针。您需要通过printArray(w->childArr, w->numChildren, sizeof w->childArr[0], printString); 。或者,以更wantarray的方式:

printString

您的printArray函数执行了错误的类型转换。您必须记住char*将指向当前元素的指针传递给回调。由于您对char**数组进行迭代,因此会传递void printString(void *vpStr) { char **pStr = vpStr; printf("[ %s ]", *pstr); } 。考虑到这一点:

/wp-content/cache/supercache/$http_host/$cache_uri/index.html

答案 1 :(得分:0)

仅供参考,您使用的方法是传统上在C中完成的方法。但在现代C中,您可以更好地编写此类通用函数:类型安全且无需函数指针:

#include <stdio.h>
#include <string.h>

#define print_array(data, n)         \
  _Generic((*data),                  \
           int: print_int,           \
           char: print_char)(data,n) \


void print_int (const int* data, size_t n)
{
  for(size_t i=0; i<n; i++)
  {
    printf("%d ", data[i]);
  }
}

void print_char (const char* data, size_t n)
{
  for(size_t i=0; i<n; i++)
  {
    printf("%c ", data[i]);
  }
}



int main (void)
{
  int int_array [3] = {1, 2, 3};
  const char* char_array = "hello world";

  print_array(int_array, 3);
  printf("\n");
  print_array(char_array, strlen(char_array)); 
  printf("\n");

}