簡體   English   中英

使用C將字符串的csv文件讀取到2D char *數組

[英]Read csv file of strings to 2D char* array using C

我已經搜索並找到了解決方案,可以找到有關int,float,double,但沒有char *的多維數組的大量答案。 我想我對指針的原理有所了解,知道char,char *和char []等之間的區別,但是指向2D char指針數組的指針對我有好處。 我正在嘗試解析一個csv文件,並用字符串(char *)填充2D數組。 這是我的代碼:

#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行上出現段錯誤。 我認為這意味着我在字符串末尾缺少空指針?

調試表明varTemp正在超出范圍使用內存。 此外,當在第一個鍵之后沒有數據的行上使用帶有%.*s printf時,它將在COL 1位置以及應該有NULL指針的位置打印COL 0。 即:

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.....

我很困惑,有什么想法嗎?

您永遠不會為varTemp分配空間,您需要為scanf() d字符串存儲空間,因此您可以嘗試執行此操作

char varTemp[100];

scanf()這樣

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

然后varTemp通過malloc()然后將strcpy()復制varTemp字符串到數組。

您需要復制字符串的原因是因為您將在隨后對sscanf()調用中將其覆蓋,因此您將其復制並將varTemp用作存儲scanf() ed字符串的緩沖區。

同樣不要轉換malloc() ,並且!feof(fp)while循環中檢查是多余的,它永遠不會成立,因為當您到達文件末尾時, fgets()將返回NULL ,然后返回該feof()為true,因此永遠不會評估返回true的時間。

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

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

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

最后,如果COLSROWS是固定值,則絕對不需要malloc()除非稍后要調整數組大小或它們太大而無法容納它們。

char *varTemp是一個指針,為了使其有效,它應該指向某個地方,您可以通過malloc()從OS請求某個地方來使其指向某個地方,例如

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.
 */

我並不是唯一一種指向某個位置的方法,而是可以動態分配空間,當發現需要多少字節然后索要那個字節數時,這通常是合適的解決方案,僅此而已。沒什么,但這也可以

char array[100];
char *varTemp;

varTemp = array;

c中的數組會衰減到指針,因此上述內容有效,並且在此示例中varTemp也可訪問,並且您可以例如sscanf(sourceString, "%99s", varTemp);

但是當你沒有指向你的指針任何有效的內存地址,試圖訪問它是未定義的行為,因為當指針指向它沒有定義

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM