简体   繁体   中英

Matrix read from a file in C

I have two matrices in a file in the following format:

17.053 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

1 3 1 4
0 5 0 4
2 1 2 4

These are just two arbritary matrices and they are always seperated by an empty line. They can be of any size and shape. I have the following code that reads the two matrices and finds out the number of rows and columns of each. How do I go about inputting these into the two matrices defined as mat_A and mat_B ?

I have tried fscanf but I print out only 0s. How do I read in the values to my two 2d arrays that are supposed to hold them?

int main(void)
{

    int space_count = 0;
    int i = 0;
    int j = 0;;
    FILE *fp;
    fp =  fopen("inputformat", "r");
    if(fp == NULL)
        printf("File not read!");
    int NumCols_first, NumCols_second, NumRows_first, NumRows_second;
    int issecondmatrix = 0;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    double **mat_A = (double **) malloc(NumRows_first * sizeof(double*));
    for(i=0; i<NumRows_first; i++)
        mat_A[i] = (double *) malloc(NumCols_first * sizeof(double));

    double **mat_B = (double **) malloc(NumRows_second * sizeof(double*));
    for(i=0; i<NumRows_second; i++)
        mat_B[i] = (double *) malloc(NumCols_second * sizeof(double));

    while((read = getline(&line, &len, fp)) != -1){
        printf("Line is of length : %u \n", read);
        printf("Line is:%s\n", line);
        for(i=0; i<read; i++){
            printf("%c\n", line[i]);
            if(line[i] == ' ')
                space_count++;
            if(read == 1){
                printf("Next matrix gonna start after this\n"); 
                NumRows_first = j;
                issecondmatrix = 1;
                j = 0;
            }   
        }
        if(j==1 & issecondmatrix == 0)
            NumCols_first = space_count + 1;
        if(j==1 & issecondmatrix == 1)
            NumCols_second = space_count + 1; 
        space_count = 0;
        j++;
    }
    NumRows_second = j - 1;
    printf("num of columns in first matrix is %d\n", NumCols_first);
    printf("number of rows in first matrix is %d\n", NumRows_first);
    printf("num of columns in second matrix is %d\n", NumCols_second);
    printf("num of rows in second matrix is %d\n", NumRows_second);
    for(i=0; i<NumRows_first)
    {
    for(j=0; j<NumCols_first; j++)
    {
        if(!(fscanf(fp, "%lf", &mat_A[i][j]))
            break;
        printf("%lf", mat_A[i][j]);
    }
}
enter code here




    free(line);
    fclose(fp);
}   

There are several mistakes in your example code, the obvious one is the matrix size is not initiated before memory allocation. You either first scan through the file to find the size of matrix and allocate memory, then scan through the 2nd time to fill the matrix; or you can allocate a big enough memory first, then fill it while scan through the file. Here is a working example with many error checking ignored (for shorter code).

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

int parse_empty(char *word)
{
    for(; *word!='\0'; word++)
        if(!isspace(*word))
            break;
    return (*word=='\0');
}

int parse_line(char *line, float *data, int max)
{
    int n=0; char *p=line, *left=line;
    while((p=strchr(left, ' '))!=NULL) {
        *p='\0';
        if((n<max) && (!parse_empty(left))) {
            data[n] = atof(left);
            n++;
        }
        left = p+1;
    }
    if(!parse_empty(left)) {
        data[n] = atof(left);
        n++;
    }
    return n;
}

#define MAX_LINESZ 128
void parse_matrix(FILE *fp, float *data, int max, int *mm, int *nn)
{
    int m=0, n=0; char *line; size_t len=MAX_LINESZ;
    line = malloc(len*sizeof(char));
    while(getline(&line, &len, fp)!=-1) {
        if(parse_empty(line))
            break;
        n = parse_line(line, data, max);
        data = data+n;
        max  = max-n;
        m++;
    }
    free(line);
    *mm=m; *nn=n;
}

//data must be malloc/calloc memory!
float **matrix_realloc(float *data, int max, int m, int n)
{
    assert(max>=m*n);
    float **mat;
    mat = malloc(m*sizeof(float*));
    mat[0] = realloc(data, m*n*sizeof(float));
    for(int i=1; i<m; i++)
        mat[i] = mat[i-1]+n;
    return mat;
}
void matrix_free(float **matrix)
{
    free(matrix[0]);
    free(matrix);
}

#define MAX_MATRIX (8*8)
int main()
{
    float *data1, *data2;
    int m1, m2, n1, n2;

    FILE *fp = fopen("t.dat", "r");
    data1 = malloc(MAX_MATRIX*sizeof(float));
    data2 = malloc(MAX_MATRIX*sizeof(float));
    parse_matrix(fp, data1, MAX_MATRIX, &m1, &n1);
    parse_matrix(fp, data2, MAX_MATRIX, &m2, &n2);

    float **mat1 = matrix_realloc(data1, MAX_MATRIX, m1, n1);
    float **mat2 = matrix_realloc(data2, MAX_MATRIX, m2, n2);
    for(int i=0; i<m1; i++) {
        printf("1>");
        for(int j=0; j<n1; j++) 
            printf(" %8.2f", mat1[i][j]);
        printf("\n");
    }
    for(int i=0; i<m2; i++) {
        printf("2>");
        for(int j=0; j<n2; j++) 
            printf(" %8.2f", mat2[i][j]);
        printf("\n");
    }
    matrix_free(mat1);
    matrix_free(mat2);
    fclose(fp);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM