2017-01-23 180 views
0

我想在C中寫一個通用的打印數組函數,並以某種方式它不能很好地處理字符串數組。 這裏的主:C通用打印數組函數 - 打印字符串數組

#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"); 
} 

打印第二工人的數據和去「孩子」陣列,代碼休息後...

任何想法爲什麼?我該如何解決它?

編輯此之後:printArray(w->childArr,w->numChildren,sizeof(w->childArr[0]),printString);

這個:printf("[ %s ]",str);

我現在有以下打印: img1

+0

好,'的printf(「[%s]的」,* STR);'肯定是不好,和你的編譯器應該扔了一個大胖子警告信息,告訴你。 'str'是'char *',所以'* str'是'char',這對'%s'來說並不好。基本上,當你承諾給它一個指向char的指針並給它指定char時,你就騙過了'printf'。而且,不需要'char * str =(char *)s;'中的強制轉換。在C中轉換或從類似const的'void *'是自動的。 – WhozCraig

+0

您不使用正確的類型'size_t'進行索引。並且你什麼也不施展,「Worker * w =(Worker *)worker;'=>'Worker * w = worker;' – Stargateur

+0

@Stargateur - 編譯器無關緊要。 – LjTiNo

回答

1

這裏這條線:

printArray(w->childArr,w->numChildren,LEN,printString); 

您傳遞LEN作爲數組中元素的大小,這可能是大於數組元素的大小。這使得printArray中的循環不在數組邊界之外,其中任何訪問都是未定義的行爲。

你的數組包含指向字符串的指針。您需要通過sizeof(char*)。或者,更D.R.Y方式:

printArray(w->childArr, w->numChildren, sizeof w->childArr[0], printString); 

printString功能做了錯誤的類型轉換。您必須記住printArray將指向當前元素的指針傳遞到回調函數中。由於你迭代了一個char*數組,它將通過一個char**。考慮到這一點:

void printString(void *vpStr) { 
    char **pStr = vpStr; 
    printf("[ %s ]", *pstr); 
} 
+0

好吧..它解決了一半的問題......現在它打印..但不是我要求它打印......你能看看我的問題的編輯? – LjTiNo

+0

@LiTiNo - 查看我的編輯。類型擦除需要一點關注細節。 – StoryTeller

+0

我必須用char ** str =(char **)s來做; (idk爲什麼我的編譯器不會讓我沒有鑄造..),但它的工作原理!你太棒了! :) – LjTiNo

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"); 

}