簡體   English   中英

如何將文件中的數據讀入C中的二維數組?

[英]How to read data from file into two dimension array in C?

我正在嘗試從文件中讀取並打印出文件中的內容。 文件中的數據類似於以下內容,由 100 行和 10 列組成。

-1,0.53,1,1,1,0,0.8,1,0.5,0

這是我嘗試過的:

    #include <stdio.h>
    #include <stdlib.h>
    #define NUMBEROFINPUT 100 //100 inputs.
    #define NUMBEROFCOLUMN 10 //10 rows.

    int main(){
        int *dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];

        FILE *dataFileptr;
        dataFileptr = fopen("group5_8.txt", "r");
        if (dataFileptr == NULL){
           perror("Error");
           return 1;
        }

        for(int i = 0; i < NUMBEROFINPUT; ++i){
            for(int j = 0; j < NUMBEROFCOLUMN; ++j){
               fscanf(dataFileptr, " %f", &dataFileInput[i][j]);
               printf("a[%d][%d] = %.2f\n", i+1,j+1, dataFileInput[i][j]);
            }
        }
    }

但是,當我打印出結果時,我只得到0.00 我對 C 編程還是比較陌生。 我究竟做錯了什么?

您也可以使用getline遵循另一種方法

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

#define NUMBEROFINPUT 2 //100 inputs.
#define NUMBEROFCOLUMN 10 //10 rows.

int main(){
    int i, j;
    float dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];
    FILE *dataFileptr;
    char* aline = NULL;
    size_t size = 0;

    dataFileptr = fopen("group5_8.txt", "r");
    if (dataFileptr == NULL){
       perror("Error");
       return 1;
    }
    while(getline(&aline, &size, dataFileptr) != -1) 
    {
        line[strcspn(aline, "\n")] = 0;
        char * sep = strtok(aline, ",");
        printf("%s\n", sep);
        while((sep = strtok(NULL, ",")) != NULL) 
        {
            printf("%s\n", sep);
        }
    }
    return 0;
}

聲明一個二維數組然后循環填充文件中的每個元素是編寫輸入例程的一種非常脆弱的方式。 如果一個浮點數太少會怎樣? (您調用未定義行為並且所有賭注都已關閉)

一個好的方法是面向行的方法,您一次讀取一行浮點數,然后使用strtok() (或者如果可能為空字段, strsep() )從每一行解析所需的浮點數,或者您可以使用一對指針和strtof()來處理一行,或者每行使用已知的固定數量的浮點數, sscanf()就可以了。 所有都允許驗證每個浮點讀取。

你能用fscanf()一次讀取一個浮點數嗎? 當然,您只需要保留單獨的計數器,當讀取一行浮點數時,重置列數並增加行數。 重復直到行數用完,或者文件結束。 無論哪個先發生。 一次讀取一個float另一個警告是您需要某種方法來驗證每一行是否具有正確的浮點數。 您可以通過設置一個單獨的變量來包含第一行中的列數,然后將每個連續行中的數字與第一行計數進行比較。

你可以這樣做:

    char c;
    int rows = 0, col = 0, cols = 0, rtn;
    float dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];
    ...
    while (rows < NUMBEROFINPUT) { /* while less than NUMBEROFINPUT rows */
        /* read float saving character that follows and the return */
        rtn = fscanf (dataFileptr, "%f%c", &dataFileInput[rows][col], &c);
        if (rtn < 1)                        /* if nothing read or EOF, break */
            break;
        else if (rtn == 1 || c == '\n') {   /* if only float read or next is \n */
            col++;                          /* increment no of col */
            rows++;                         /* increment no. of rows */
            if (cols && col != cols) {      /* if cols set validate cols no. in col */
                fprintf (stderr, "error: unequal number of columns, row: %d\n", rows);
                return 1;
            }
            if (!cols)                      /* if first row, set no. of cols */
                cols = col;
            col = 0;                        /* reset col for next row */
        }
        else            /* both values read and char not '\n' */
            col++;      /* increment col count */
    }
    
    for (int i = 0; i < rows; ++i)          /* output results */
        for (int j = 0; j < cols; ++j)
           printf("a[%d][%d] = %.2f\n", i+1,j+1, dataFileInput[i][j]);

通過使用上面的colrows索引,您可以跟蹤讀取的狀態。 通過返回if (cols && col != cols) ,在cols由第一行列數設置后,您強制所有后續行包含該數量的值,以確保您的 2D 數組完全填充。

示例使用/輸出

dataFileptr設置為stdin並使用stdin讀取示例輸入將導致:

$ ./bin/read2Dcsv <<< -1,0.53,1,1,1,0,0.8,1,0.5,0
a[1][1] = -1.00
a[1][2] = 0.53
a[1][3] = 1.00
a[1][4] = 1.00
a[1][5] = 1.00
a[1][6] = 0.00
a[1][7] = 0.80
a[1][8] = 1.00
a[1][9] = 0.50
a[1][10] = 0.00

有很多方法可以做到這一點。 面向行的方法提供了最靈活和健壯的方法,但您也可以使一次float方法相當靈活。 如果您有任何其他問題,請告訴我。

您應該更改以下行:

int *dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];

如下:

float dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];

或者,您可以將數組聲明為double並使用%lf讀取

我還必須按如下方式跳過逗號:

#include <stdio.h>
#include <stdlib.h>
#define NUMBEROFINPUT 100 //100 inputs.
#define NUMBEROFCOLUMN 10 //10 rows.

int main(){
    float dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];
    
    FILE *dataFileptr;
    dataFileptr = fopen("group5_8.txt", "r");
    if (dataFileptr == NULL){
       perror("Error");
       return 1;
    }

    for(int i = 0; i < NUMBEROFINPUT; ++i){
        for(int j = 0; j < NUMBEROFCOLUMN; ++j){
           fscanf(dataFileptr, "%f", &dataFileInput[i][j]);
           fgetc(dataFileptr);
           printf("a[%d][%d] = %.2f\n", i+1,j+1, dataFileInput[i][j]);
        }
    }
    
    fclose(dataFileptr);
}

注意對fgetc的調用。

為了完成起見,我希望您注意,即使使用 int* 數組,讀取也是成功的。 打印失敗,因為數據被解釋為 int*,然后轉換為浮點數。 要解釋存儲在 int* 數組元素中的字節,首先將元素的地址強制轉換為指向浮點數的指針,然后獲取存儲在該地址的浮點數的值。 除了打印語句外,相同的代碼。

#include <stdio.h>
#include <stdlib.h>
#define NUMBEROFINPUT 100 //100 inputs.
#define NUMBEROFCOLUMN 10 //10 rows.

int main(){
    int *dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];
    
    FILE *dataFileptr;
    dataFileptr = fopen("group5_8.txt", "r");
    if (dataFileptr == NULL){
       perror("Error");
       return 1;
    }

    for(int i = 0; i < NUMBEROFINPUT; ++i){
        for(int j = 0; j < NUMBEROFCOLUMN; ++j){
           fscanf(dataFileptr, "%f", &dataFileInput[i][j]);
           fgetc(dataFileptr);
           printf("a[%d][%d] = %.2f\n", i+1,j+1, *((float *) &dataFileInput[i][j]));
        }
    }
    
    fclose(dataFileptr);
}

暫無
暫無

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

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