2014-03-30 67 views
1

我是C的新手,在使用和理解指針方面 - 特別是void指針時,我仍然很弱。我試圖編寫一個從文件加載數據的函數,並將這些數據存儲在一個void指針數組中,這樣數組的每個元素(在本例中)都具有該文件行中的字符串。我懷疑是有一些問題的代碼:C:使用void指針數組工作

  1. 我不知道如果我正確使用* voidArray []作爲函數的參數之一。
  2. 我不確定strcpy()是否是將行緩衝區內容複製到相關數組元素的好方法。
  3. 我不知道strcpy()的目的地(即void指針數組中的相關元素)的正確語法。

也可能有其他錯誤,但這些是我感到非常不確定的三個問題。

這裏是我的功能:

void *readData(void *voidArray[], const char *filename, int lines) { 
    FILE *stream = fopen(filename, "r"); 
    if (stream == NULL) { 
     perror("Error loading file"); 
    return 1; 
    } 
    char lineBuffer[BUFFER_SIZE]; 

int i = 0; 
    while(!feof(stream)) { 
     while(fgets(lineBuffer, sizeof(lineBuffer), stream)) { 
      // *voidArray[i] = malloc(strlen(lineBuffer) + 1);  // probably not what I want 
      strcpy(*voidArray[i], lineBuffer); 
      i++; 
     } 
    } 

    fclose(stream); 
} 

...這是)的主要開始(其中,(再次)我不知道正確的語法是什麼聲明數組(和初始化?) :

int main(void) 
{ 
    int lines = 20; 
    void *varray[lines]; 
    // varray = malloc(sizeof(char *) * lines);  // probably not what I want 
    readData(varray[lines], FILENAME, lines);  // FILENAME declared earlier 

一些建議代碼修復將非常感謝(尤其是如果我完全缺少一個更合適的方法船),但我覺得我需要更多的是爲什麼一個很好的解釋這些建議是正確的。如果我能把這個問題包括在內,我認爲 - 最糟糕的是 - 我會很清楚自己仍然需要教導自己的重點:指針。提前感謝您的幫助或評論,並請耐心等待。


編輯:約阿希姆Pileborg的答案已經幫助,但我仍然失去了一些基本(可能很明顯)。這裏是我的修訂功能:

void *loadData(void *voidArray, const char *filename, int lines) { 
    FILE *stream = fopen(filename, "r"); 
    if (stream == NULL) { 
     perror("Error loading file"); 
    } 
    char lineBuffer[BUFFER_SIZE]; 

    int i = 0; 
    while(fgets(lineBuffer, sizeof(lineBuffer), stream)) { 
     strcpy((voidArray+i), lineBuffer); 
     printf("voidArray: %s\n", (char *)(voidArray+i)); 
     i++; 
    } 

    for (i = 0; i < lines; i++) { 
     printf("array element %d: %s\n", i, (char *)(voidArray+i)); 
    } 

    fclose(stream); 
} 

這裏是從我的兩個測試的結果:

voidArray: Good 
voidArray: morning 
voidArray: everyone 
array element 0: Gmeveryone 
array element 1: meveryone 
array element 2: everyone 

同樣,我可能失去了一些東西微不足道。我想要做的是varray由void指針組成,每個指針指向一個從外部文件讀取的對象(對於這個例子來說,一個字符串)。我對「varray + i」有什麼不對,但我不知道我應該怎麼做。

+1

你不需要外循環('while(!feof(...))'循環)。實際上,如果在文件結束之前讀取文件時出現錯誤,它可能會導致無限循環。 –

+0

如果你存儲字符,爲什麼不使用char數組,char指針?你不需要這個 –

+0

啊,我認爲你對外環的冗餘是正確的。謝謝!讀取我創建的用於測試的任何文件時沒有錯誤,並且將文件行讀入緩衝區是該函數的少數幾個方面之一,我確信它正在按預期工作。 – jda

回答

2

有四個問題(除了我在評論中提到的一個),我在看一眼就看到:

  • 第一個是你註釋掉的分配,因此,如果指針AREN」當你調用這個函數時,你會分配一些內存中隨機位置。

  • 第二個是你在strcpy的調用中使用解引用操作符。如果你有例如一個char指針數組,這將是一個單一的char而不是一個指針。除此之外,您實際上不能取消引用void指針。

  • 第三個問題是,你永遠不會檢查數組中的條目數,你只是繼續循環讀取和複製到數組中,而不考慮它的大小。

  • 第四個問題是在調用此函數,在這裏實際上不傳遞指針的數組,但單一的指針的索引lines,這將是一個超出陣列的界限的樣子。


到無關的邊注:請記住,如果fgets讀取一個換行符,那麼換行符會在緩衝區中。

+0

非常感謝!我有兩個問題,如果沒關係: 1.我不確定我是否理解第三個問題。主要指定數組的特定數量的元素(即文件中的行數)。 2.如何解決問題4? – jda

+0

@jda您將數組中元素的數量傳遞給函數('lines'參數),您必須讓您永遠不會讀取超過此數值(並且請記住,數組索引的範圍從零到大小減1) 。對於第二個問題,不要使用數組索引。 –

+0

再次感謝您。我已經更新了我的問題,並希望稍微縮小它的範圍。我的問題是,我不知道我應該使用什麼樣的語法來訪問陣列中的各種空指針而不使用數組索引。我做了一個嘗試,但打印的測試表明我的索引不正確。我想,如果我能理解這一部分,我應該處於能夠探索和調查而不會感到筋疲力盡的地步。 – jda

-2

你不能在void指針中存儲東西,也不能索引它們。除非先施放它們,否則無法取消引用void指針。你不能對它們進行指針運算。它們是後來添加的泛型語法糖,因爲人們使用char *來達到這個目的。

+0

爲什麼downvotes?我錯了嗎? – avmohan

+0

您可以將任何數據地址存儲在空指針中... – Deduplicator

+0

'void * x; * x = 5;'是非法的,我的意思是。相比之下,'int * x; * x = 5;'是合法的 – avmohan