簡體   English   中英

從C中的文件讀取2D數組

[英]Reading a 2D array from a file in C

我正在嘗試創建一個程序來從文件中讀取2D數組,然后將其打印出來。

設置文件的位置,使第一行具有行數,然后具有列數。 之后,繪制陣列。 示例如下:

3 5
10.4 15.1 18.5 13.3 20.8
76.5 55.3 94.0 48.5 60.3
2.4 4.6 3.5 4.6 8.9

我的問題是我只知道如何使用fgets和sscanf讀取每一行的第一個元素,因此以下數字將被忽略。

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

int main(int argc, char* argv[]){

FILE* f = fopen("plottestdata", "r");
char size[20];
int height, width,ii=0,cc,jj,kk;
float array[100][100];
char horiz[500];

if(fgets(size, 20, f)!= NULL){

    sscanf(size,"%d %d", &height, &width);
    printf("%d %d\n",height, width);
}
while(fgets(horiz, 500, f)!=NULL)
{

    if(ii<height)
    {
        for(cc=0;cc<width;cc++)
        {
        sscanf(horiz, "%f", &array[ii][cc]);
        }
    ii++;
    }
}
for(jj=0;jj<width;jj++)
    {
        for(kk=0;kk<height;kk++)
        {
        printf("%f ", array[jj][kk]);
        }
    }
fclose(f);
return 0;
}

這給了我每行第一元素重復多次的輸出,我理解為什么但不確定如何解決它。 盡管讀取的文件格式與示例相同,但實際上是20x20的數組。

另外,為了簡化簡短的問題,我省略了錯誤檢查。

為了避免使用fgets並使用fscanf直接讀取值,我是如此抗拒調整和簡化您的代碼,它是如此接近。 加上基本的錯誤檢查。

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

#define MWIDTH  100
#define MHEIGHT 100

int main(void){

    FILE* f;
    int height, width, ii, jj;
    float array[MHEIGHT][MWIDTH];

    if((f = fopen("plottestdata.txt", "r")) == NULL)
        exit(1);

    if(fscanf(f, "%d%d", &height, &width) != 2)
        exit(1);
    if (height < 1 || height > MHEIGHT || width < 1 || width > MWIDTH)
        exit(1);

    for(jj=0; jj<height; jj++)
        for(ii=0; ii<width; ii++)
            if(fscanf(f, "%f", &array[jj][ii]) != 1)
                exit(1);
    fclose(f);

    for(jj=0; jj<height; jj++){
        for(ii=0; ii<width; ii++)
            printf ("%10.1f", array[jj][ii]);
        printf("\n");
    }
    return 0;
}

程序輸出:

  10.4      15.1      18.5      13.3      20.8
  76.5      55.3      94.0      48.5      60.3
   2.4       4.6       3.5       4.6       8.9
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]){
    FILE* f = fopen("plottestdata", "r");
    char size[20];
    int height, width,ii=0,cc,jj,kk;
    char horiz[500];

    if(fgets(size, 500, f)!= NULL){

    sscanf(size,"%d %d", &height, &width);
    printf("%d %d\n",height, width);
    }
    float array[height][width];
    while(fgets(horiz, 500, f)!=NULL)
    {

    if(ii<height)
    {
         sscanf(horiz, "%f %f %f %f %f", &array[ii][0],&array[ii][1],
                    &array[ii][2],
                    &array[ii][3],
                    &array[ii][4]);       
              ii++;
        }
    }
    for(ii=0;ii<height;ii++)
    {
        for(kk=0;kk<width;kk++)
        {
            printf("%.2f ", array[ii][kk]);
        }
        printf("\n");
    }
    fclose(f);
    return 0;
}

為什么不從stdin中讀取,而不是從具有硬編碼文件名的文件中讀取? 您可以使用fgets(size, sizeof size, stdin)讀取具有尺寸的第一行。

然后使用scanf(" %f", &array[ii][cc)逐一讀取值。

確保測試scanf是否返回1,如果沒有,則添加一些錯誤處理。

如您所知,您需要在掃描上一個值后掃描下一個中斷的值。 不幸的是, sscanf不具有流的屬性。 它不記住它的最后位置,並且如果您傳遞相同的字符串,則總是重新開始。

幸運的是,還有許多其他方法可以實現順序掃描。

標記化您可以將forst標記化,然后將每個標記解析為浮點數。 來自string.h> strtok和來自<stdlib.h> strtod將為您完成這項工作。

        char *token = strtok(horiz, " \t\n");

        for (cc = 0; cc < width; cc++) {
            if (token) {                
                array[ii][cc] = strtod(token, NULL);
                token = strtok(NULL, " \t\n");
            } else {
                array[ii][cc] = 0.0;
            }
        }

跟蹤I strtod 的尾部還有另一個特征:當您提供一個指向char指針的指針時,它可以准確告訴您解析在哪里停止。 strtod也跳過領先的空格。 您可以使用這兩個事實來解析由空格分隔的浮點數。

        char *p = horiz;

        for (cc = 0; cc < width; cc++) {
            char *tail;

            array[ii][cc] = strtod(p, &tail);
            p = tail;
        }

跟蹤尾部II sscanf具有一種特殊的格式,該格式可以告訴您在某個整數點已解析了多少個字符。 上面可以用sscanf編寫:

       char *p = horiz;

        for (cc = 0; cc < width; cc++) {
            int len;

            sscanf(p, "%f%n", &array[ii][cc], &len);
            p += len;
        }

所有這些都適用於您的示例,但是沒有一個可以進行正確的錯誤檢查。 第一個示例至少做出了三心二意的嘗試,以抓住一行令牌少於矩陣包含列的情況。

暫無
暫無

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

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