C 如何读取包含字符串和双精度的.dat文件,并将双精度写入矩阵?

C 如何读取包含字符串和双精度的.dat文件,并将双精度写入矩阵?,c,file,C,File,我有一个包含以下结构的文件: Caso Escp P1 P2 P3 P4 P5 P5+ Caos HCaos Total 0.099601 82.921184 1.459357 1.576886 0.381672 0.250597 0.392030 12.918674 0.000000 Biest 0.199601 65.802794 2.895808 3.160080 0.764870 0.502196 0.785629 25.889022 0.000000 Monoest 0.000000

我有一个包含以下结构的文件:

Caso Escp P1 P2 P3 P4 P5 P5+ Caos HCaos
Total 0.099601 82.921184 1.459357 1.576886 0.381672 0.250597 0.392030 12.918674 0.000000
Biest 0.199601 65.802794 2.895808 3.160080 0.764870 0.502196 0.785629 25.889022 0.000000
Monoest 0.000000 99.971372 0.028628 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
如您所见,它在同一个文件中有字符串和双精度。我正试着把这些双倍体写进矩阵,然后在屏幕上打印出来。我已经可以使用只包含双精度的文件来实现这一点,但是在本例中,我还没有找到解决方案

以下是我的代码示例:

#define lin 4
#define col 10
double N = 0.3;
char filename_porc[64], str[100];

int main()
{
    double mat[lin][col];       

    for (int k = 1; k < lin; k++)
    {
        for (int m = 1; m < col; m++)
        {
            printf("%f ", mat[k][m]);
        }
        printf("\n");
    }

    sprintf(filename_porc, "(N = %g) resp.dat", N); 
    input_result = fopen(filename_porc, "r");

    printf("\n\n");

    fgets(str, 100, input_result);
    for (int i = 0; i < lin; i++)
    {
        for (int j = 0; j < col; j++)
        {
            if ((i > 0) && (j > 0))
            {
                fscanf(input_result, "%g", &mat[i-1][j-1]);
                printf("%g ", mat[i-1][j-1]);
            }
        }
        printf("\n");
    }

    fclose(input_result);
    printf("\n *** End of Execution ***");
    getchar();
}
#定义lin 4
#定义第10列
双N=0.3;
char filename_-proc[64],str[100];
int main()
{
双垫[林][col];
for(int k=1;k0)和&(j>0))
{
fscanf(输入_结果,“%g”和mat[i-1][j-1]);
printf(“%g”,mat[i-1][j-1]);
}
}
printf(“\n”);
}
fclose(输入结果);
printf(“\n***执行结束***”);
getchar();
}
编辑:

fgets(str,100,输入结果);
for(int i=0;i0)和&(j>0))
{
fscanf(输入_结果,“%g”和mat[i-1][j-1]);
printf(“%g”,mat[i-1][j-1]);
}
}
printf(“\n”);
}

如您所知,您可以读取如下单个数字:

fscanf(input_result, "%g", &x);
如果要用一个命令读取两个数字,可以执行以下操作:

fscanf(input_result, "%g %g", &x, &y);
要读取后跟数字的字符串,请执行以下操作:

char str[20];
fscanf(input_result, "%s %g", str, &x);
(请注意,“str”没有带符号,因为它是一个数组。)

因此,要读取后跟多个数字的字符串,可以指定所有数字:

fscanf(input_result, "%s %g %g %g %g %g", str, &arr[0], &arr[1], &arr[2],...
或者您可以使用循环:

fscanf(input_result, "%s", str);
for(unsigned int k=0; k<col; ++k)
    fscanf(input_result, "%g", &arr[k]);

读取文件时,行、列和缓冲区的数量非常有限。这里有一个更灵活的方法使用

不过,它并非没有关于输入文件的假设:文件应该以换行结束,有固定的列,没有格式错误,第一行是标题,等等。它还经常调用
realloc
,这在实践中不会导致很多系统调用,但可以通过加倍容量而不是增加容量来加快速度。认为这是一个概念证明。

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

typedef struct matrix {
    int rows;
    int cols;
    double **data;
} matrix;

int main() {
    matrix m = {0, 0, 0};
    m.data = malloc(sizeof(double *));
    int digit_buf_len = 0;
    char digit_buf[32];
    FILE *fin = fopen("resp.dat", "r");
    int c;

    // skip the first row
    while ((c = fgetc(fin)) != EOF && c != '\n');

    for (int col = 0; (c = fgetc(fin)) != EOF;) {
        if (isdigit(c) || c == '.') {
            digit_buf[digit_buf_len++] = c;
        }
        else if (digit_buf_len) {
            if (col) {
                m.data[m.rows] = realloc(m.data[m.rows], 
                                         (col + 1) * sizeof(double));
            }
            else {
                m.data = realloc(m.data, (m.rows + 1) * sizeof(double *));
                m.data[m.rows] = malloc(sizeof(double));
            }

            digit_buf[digit_buf_len] = '\0';
            sscanf(digit_buf, "%lf", &m.data[m.rows][col]);
            memset(digit_buf, 0, digit_buf_len);
            digit_buf_len = 0;
            col++;
        }

        if (c == '\n') {
            m.cols = m.cols > col ? m.cols : col;
            m.rows++;
            col = 0;
        }
    }

    for (int i = 0; i < m.rows; i++) {
        for (int j = 0; j < m.cols; j++) {
            printf("%f ", m.data[i][j]);
        }

        free(m.data[i]);
        puts("");
    }

    free(m.data);
    fclose(fin);
    return 0;
}
如果文件更改为:

Caso Escp P1 P2 P3 P4 P5 P5+Caos HCaos
总计0.099601 82.921184 1.459357 1.576886
Biest 0.199601 65.802794 2.895808 3.160080
Mxxxxst 1.00000099.971372 1.028628 2.000000
Mxxxxst 2.00000019.971372 7.028628 3.000000
Mxxxxst 3.00000029.971372 6.028628 5.000000
Mxxxxst 4.00000029.971372 3.028628 6.000000
然后它仍然有效:

0.099601 82.921184 1.459357 1.576886
0.199601 65.802794 2.895808 3.160080
1.000000 99.971372 1.028628 2.000000
2.000000 19.971372 7.028628 3.000000
3.000000 29.971372 6.028628 5.000000
4.000000 29.971372 3.028628 6.000000

@ggorlen很抱歉把结构弄混了。实际上我更喜欢用C,所以我编辑代码以保持连贯性。谢谢你的回答。如何仅从文件中获取数字?因为我想按照你说的方式去做,但问题是。我无法跳过整个第一行字符串以开始读取第二行并应用以下内容:
fscanf(input_result,“%s”,str);对于(unsigned int k=0;kI),我们按照您的指示修改了代码,并更新了问题框上的代码,但是屏幕上的输出继续显示矩阵中的零列表。出于某种原因,它没有采用.dat文件中的值并写入矩阵中:(@Lug:打印第一行时会发生什么情况,以验证您是否正确读取了它?当您尝试将第二行中的数字读入一个简单数组(
double[col]
)时会发生什么情况)?问题是,在第二行、第三行和第四行中,它在所有数字之前仍然有一个字符串元素。为了解决这个问题,我做了我现在更新的问题的编辑部分中显示的内容。但是它在屏幕上仍然只显示零。尝试只在简单的矩阵“double[col]”中打印。仍然是相同的问题
char str[100];
fgets( str, 100, input_result);
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct matrix {
    int rows;
    int cols;
    double **data;
} matrix;

int main() {
    matrix m = {0, 0, 0};
    m.data = malloc(sizeof(double *));
    int digit_buf_len = 0;
    char digit_buf[32];
    FILE *fin = fopen("resp.dat", "r");
    int c;

    // skip the first row
    while ((c = fgetc(fin)) != EOF && c != '\n');

    for (int col = 0; (c = fgetc(fin)) != EOF;) {
        if (isdigit(c) || c == '.') {
            digit_buf[digit_buf_len++] = c;
        }
        else if (digit_buf_len) {
            if (col) {
                m.data[m.rows] = realloc(m.data[m.rows], 
                                         (col + 1) * sizeof(double));
            }
            else {
                m.data = realloc(m.data, (m.rows + 1) * sizeof(double *));
                m.data[m.rows] = malloc(sizeof(double));
            }

            digit_buf[digit_buf_len] = '\0';
            sscanf(digit_buf, "%lf", &m.data[m.rows][col]);
            memset(digit_buf, 0, digit_buf_len);
            digit_buf_len = 0;
            col++;
        }

        if (c == '\n') {
            m.cols = m.cols > col ? m.cols : col;
            m.rows++;
            col = 0;
        }
    }

    for (int i = 0; i < m.rows; i++) {
        for (int j = 0; j < m.cols; j++) {
            printf("%f ", m.data[i][j]);
        }

        free(m.data[i]);
        puts("");
    }

    free(m.data);
    fclose(fin);
    return 0;
}