2016-07-14 33 views
1

我正在編寫一個程序,它正在做一件簡單的任務;逐行讀取一個文件,解析它,並將結果存儲到一個數組中,其中結構爲array [lineNumber] [lineElement]。除了我遇到的一個奇怪的問題之外,它的大部分工作都很有效。數組結果在while循環內是正確的,但在其外部破壞

在下面的代碼中,對數組進行訪問的數組只包含填充它的while循環的外部數據,只返回最後一個條目。無論lineNumber的關鍵是什麼都會發生。基本上它就像覆蓋一樣,儘管在while循環內它可以很好地訪問。我認爲只有兩個項目可能會出錯,我用粗體略述,儘管對於char * processData [100];,它不應該是一個問題,因爲它存儲在一個聲明在while循環之外的數組中(如果我記得正確的while循環不應該有範圍?),而另一行** char ** processArray [100] ; **,它可能是指針數組的雙星,但將它返回給一顆星則會引發一連串的錯誤,即前面提到的數組結構完全中斷。

所以簡而言之,不是以任何方式成爲C專家,並且耗盡我的資源來解決這個問題,我想知道這裏的C編碼人員是否可以提供一些關於發生了什麼事情的建議,以及如何獲得這要按預期工作......如果我能的話。

如前所述,代碼。

#include <ctype.h> 
#include <stdbool.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) { 

    FILE *ifp; 
    char line[80]; 
    int returnValue = 0; 

    //Open file 
    ifp = fopen("dataFile", "rt"); 

    if (ifp == NULL) { 
     fprintf(stderr, "Can't open input file!\n"); 
     returnValue = 1; 
    } 

    int lineCounter = 0; 
    char **processArray[100]; 

    while(fgets(line, 80, ifp) != NULL) { 

     char *processData[100]; 

     char *p = strtok(line, " ,\n"); 

     int keyCounter = 0; 

     while (p != NULL) { 
      processData[keyCounter] = p; 
      p = strtok(NULL, " ,\n"); 

      keyCounter++; 
     } 

     processArray[lineCounter] = processData; 

     printf("%d\n", lineCounter); 
     printf("Inside -> %s\n", processArray[0][0]); 
     lineCounter++; 
    } 
    printf("Outside %s\n", processArray[0][0]); 
    fclose(ifp); 

    int i; 
    int j; 

    for (i = 0; i < 4; i++) { 
     for (j = 0; j < 4; j++) { 
      printf("%d-%d => %s\n ", i, j, processArray[i][j]); 
     } 
    } 

    return returnValue; 
} 
+0

每次通過外循環時,你會在你的'line []'數組中讀入一行,覆蓋之前的內容。但前一行的指針集仍然指向該數組。您可能要調用'malloc'來爲每行文本分配一個全新的數組。 –

回答

2

[幾乎]所有東西都被外層while循環覆蓋,所以只剩下最後一條處理過的線。中間結果必須保留

我已經修復了有關錯誤的註釋程序。風格是#if 0 /* original code */ #else /* fixed code */ #endif

#include <ctype.h> 
#include <stdbool.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int 
main(void) 
{ 
    FILE *ifp; 
    char line[80]; 
    int returnValue = 0; 

    //Open file 
    ifp = fopen("dataFile", "rt"); 

    if (ifp == NULL) { 
      fprintf(stderr, "Can't open input file!\n"); 
      returnValue = 1; 
    } 

    int lineCounter = 0; 
    char **processArray[100]; 

    // NOTE/BUG: things get lost on each iteration of this loop 
    while(fgets(line, 80, ifp) != NULL) { 
      char *processData[100]; 

      char *p = strtok(line, " ,\n"); 

      int keyCounter = 0; 

      while (p != NULL) { 
      // NOTE/BUG: p will get overwritten -- so we must save the string 
#if 0 
        processData[keyCounter] = p; 
#else 
        processData[keyCounter] = strdup(p); 
#endif 
        p = strtok(NULL, " ,\n"); 

        keyCounter++; 
      } 

      // NOTE/BUG: processData must be duplicated -- it is overwritten 
      // on the outer loop 
#if 0 
      processArray[lineCounter] = processData; 
#else 
      char **pA = malloc(sizeof(char *) * keyCounter); 
      processArray[lineCounter] = pA; 
      for (int copyidx = 0; copyidx < keyCounter; ++copyidx) 
       pA[copyidx] = processData[copyidx]; 
#endif 

      printf("%d\n", lineCounter); 
      printf("Inside -> %s\n", processArray[0][0]); 
      lineCounter++; 
    } 
    printf("Outside %s\n", processArray[0][0]); 
    fclose(ifp); 

    int i; 
    int j; 

    for (i = 0; i < 4; i++) { 
      for (j = 0; j < 4; j++) { 
        printf("%d-%d => %s\n ", i, j, processArray[i][j]); 
      } 
    } 

    return returnValue; 
} 
+0

按預期的方式工作,謝謝。此外,感謝您解釋爲什麼會發生這種情況,並說明它應該是什麼,而不是代碼本身的內容。作爲一名視覺學習者,它使事情變得更容易。謝謝您的回覆。 – canadiancreed

+0

不客氣。感謝您對#if 0的反饋。我已經開始越來越多地[儘可能]做到這一點。你的代碼已經足夠好了,我可以將'NOTE/BUG'和修補程序結合在一起。對於某些問題,我必須在一個代碼塊中註釋錯誤,並在另一個代碼塊中提供修復,因爲代碼需要比您更多的重構。 –

1

processData被分配在堆棧上的內存地址無效,你離開後while循環,無論你將它存儲在processArray的。你需要從堆中分配(使用malloc或其他內存分配函數)

+0

當解釋出這種感謝時,這是有道理的。作爲一個習慣於爲我處理內存管理的語言的人,讓我的頭腦在堆棧和堆上看起來總是讓我陷入循環。感謝您的回覆。 – canadiancreed