2015-02-11 53 views
-1

我已經搜索並搜索瞭解決方案,可以找到關於int,float,double,但不包含char *的多維數組的大量答案。我認爲我掌握了指針的原理,知道char,char *和char []等之間的區別,但是指向二維char指針數組的指針已經變得更好了。我試圖解析一個csv文件,並用字符串(char *)填充我的二維數組。這裏是我的代碼:使用C讀取csv文件的字符串到2D char *數組使用C

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

#define COLS 10 
#define ROWS 1000 

int main (void) { 
     char***myarray; 
     FILE *fp; 
     char charTemp[100]; 
     char *varTemp = NULL; 
     char *strTemp = NULL; 
     int i, j; 

     // allocate memory to hold array ROWS 
     if ((myarray = (char***) malloc(ROWS * sizeof(char**))) == NULL) 
      return -1; 

     // then allocate memory to hold array COLS 
     for (i = 0; i < ROWS; i++) 
     { 
      if ((myarray[i] = (char**) malloc(COLS * sizeof(char**))) == NULL) 
       return -2; 
     } 

     // read file 
     if ((fp = fopen ("myfile.csv", "r")) == NULL) 
      return -3; 

     // parse and fill 'myarray' 
     i = 0; 
     j = 0; 

     while (!feof(fp) && fgets(charTemp, sizeof charTemp, fp)) { 
       strTemp = strtok(charTemp, ","); 
       while (strTemp != NULL) { 
        sscanf(strTemp, "%s", &varTemp); 
        myarray[i][j] = varTemp; 
        printf("%s ", myarray[i][j]); 
        j++; 
        if (j > COLS - 1) 
         j = 0; 
        strTemp = strtok(NULL, ","); 
       } 
       printf("\n"); 
       i++; 
      } 
     return 0; 
} 

myfile.csv看起來是這樣的:

ABCD,1,0.2,0.5,0,A123,ZZ,1,120,1 
BCDE,1.038,0,0.525,0,B321,YY,1.25,100,0.7 
CDEF,1,0.2,0.5,0,C3P0,XX,1,120,1 
DEFG,,,,,,,,, 
EFGH,1,0.3,0.8,0,R2D2,WW,1.25,120,1 
FGHI,,,,,,,,, 
etc..... 

我知道有些是整型和浮點等,但我想他們都去爲char *然後我就可以ATOI或者什麼時候我需要使用它們。

printf只是查看我已加載測試的內容。如果我使用令牌%。* s顯示,如果使用%s,則在printf行處顯示segfaults。我認爲這意味着我在我的字符串末尾缺少空指針?

調試建議varTemp使用內存越界。此外,在第一個鍵後沒有數據的行上使用帶有%.*s的printf時,它將在COL 1位置打印COL 0以及應該有NULL指針。即:

ABCD 1 0.2 0.5 0 A123 ZZ 1 120 1 
BCDE 1.038 0 0.525 0 B321 YY 1.25 100 0.7 
CDEF 1 0.2 0.5 0 C3P0 XX 1 120 1 
DEFG DEFG 
EFGH 1 0.3 0.8 0 R2D2 WW 1.25 120 1 
FGHI FGHI 
etc..... 

我很困惑,有什麼想法?

+0

'char *** myarray;'......不,我不是一個三星程序員。我也很困惑:-) – 2015-02-11 11:27:35

+1

首先,[在C中你不應該使用'malloc'結果](http://stackoverflow.com/questions/605845/do-i-cast-the-result-的-的malloc)。要繼續,請看看分配內存的第二個循環,以及它分配的內容。然後意識到你所設置的所有'myarray [i] [j]'指針,你設置的完全一樣。 – 2015-02-11 11:28:43

+1

哦,你不需要在循環條件中檢查'!feof(fp)',如果你在*'feof(fp)之前命中文件結束並退出循環,'fgets'將返回'NULL'返回true。 – 2015-02-11 11:30:35

回答

2

你從不爲varTemp分配空間,你需要的scanf() d字符串空間存儲,所以你可以試試這個

char varTemp[100]; 

scanf()這樣

sscanf(strTemp, "%99s", varTemp); 

,然後複製varTemp字符串由malloc() ing,然後strcpy() ing。

您需要複製字符串的原因是因爲您將在後續調用sscanf()時覆蓋它,因此您將其複製並使用varTemp作爲緩衝區來存儲scanf() ed字符串。

而且Don't cast malloc(),這!feof(fp)檢查在while環是多餘的,它永遠不會是真實的,因爲當你到達文件的末尾fgets()將返回NULL並在那之後feof()將是真實的,所以它從來沒有當評估它會返回true。

它不會在這種情況下,因爲sizeof(char *) == sizeof(char **)重要,但作爲一項規則,你應該malloc()一個明星小於指針,你是malloc()荷蘭國際集團的,所以

if ((myarray[i] = malloc(COLS * sizeof(char *))) == NULL) 

會更容易理解,並且在失敗時你只需從main()返回而不釋放先前分配的指針。

最後,如果COLSROWS是固定值,也絕對沒有必要malloc()除非你的陣列將在稍後調整或他們是太大堆棧來保存它們。

char *varTemp是一個指針,它是有效的,應該指向的地方,你可以把它通過malloc()通過請求來自操作系統,somewher點的地方,像

char *varTemp; 
varTemp = malloc(NumberOfBytesIWant); 
if (varTemp == NULL) 
    ohNo_TheSystemDidNotGiveMeMemory_PerhapsThereIsNoMemoryLeft_IShouldNotContinue(); 
/* now varTemp is accessible and you are allowed to write NumberOfBytesIWant 
* into it. But you must remember to calll 'free(varTemp)' later when you no 
* longer need the data. 
*/ 

I'ts不是唯一的方法你可以把它指向某個地方,這樣你就可以動態地分配空間,而且當你找到需要的字節數時,這通常是適當的解決方案,然後只需要索要這個數量,沒有其他的東西,不過也是這樣工作

char array[100]; 
char *varTemp; 

varTemp = array; 

數組在c衰減到指針,所以上面是有效的,在這個例子中varTemp也可以訪問,你可以例如sscanf(sourceString, "%99s", varTemp);

但是,當您沒有指向任何有效的內存地址與您的指針,嘗試訪問它是未定義的行爲,因爲它的未定義指針指向。

+0

感謝iharob,非常豐富。澄清,如何來char * varTemp是不好的和char varTemp [100]是必需的? sscanf是否需要一個字符數組來用作緩衝區而不是鏈接列表? – Charlton 2015-02-11 13:37:13

+0

@ user4554380我想我現在已經說清楚了,如果我沒有請讓我知道。 – 2015-02-11 13:52:00

相關問題