首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何读取包含字符串和双精度数的.dat文件,并将双精度数写在矩阵上?

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

Stack Overflow用户
提问于 2019-06-15 07:33:08
回答 2查看 195关注 0票数 2

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

代码语言:javascript
复制
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

正如您所看到的,它在同一文件中包含字符串和双精度。我正试着把这些双倍数写成一个矩阵,然后打印在屏幕上。我已经可以通过只包含doubles的文件做到这一点,但是在这种情况下,我还没有找到解决方案。

下面是我的代码示例:

代码语言:javascript
复制
#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();
}

编辑:

代码语言:javascript
复制
fgets(str, 100, input_result);

    for (int i = 0; i < lin; i++)
    {
        for (int j = 0; j < col; j++)
        {
            if (j == 0) { fscanf(input_result, "%s", str); }

            if ((i > 0) && (j > 0))
            {
                fscanf(input_result, "%g", &mat[i-1][j-1]);
                printf("%g ", mat[i-1][j-1]);
            }
        }
        printf("\n");
    }
EN

回答 2

Stack Overflow用户

发布于 2019-06-15 08:07:34

正如您已经知道的,您可以像这样读取单个数字:

代码语言:javascript
复制
fscanf(input_result, "%g", &x);

如果你想用一个命令读取两个数字,你可以这样做:

代码语言:javascript
复制
fscanf(input_result, "%g %g", &x, &y);

要读取后跟数字的字符串,请执行以下操作:

代码语言:javascript
复制
char str[20];
fscanf(input_result, "%s %g", str, &x);

(请注意,"str“没有”与“符号,因为它是一个数组。)

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

代码语言:javascript
复制
fscanf(input_result, "%s %g %g %g %g %g", str, &arr[0], &arr[1], &arr[2],...

或者你可以使用一个循环:

代码语言:javascript
复制
fscanf(input_result, "%s", str);
for(unsigned int k=0; k<col; ++k)
    fscanf(input_result, "%g", &arr[k]);

编辑:读取整个第一行,确保str足够大,并使用fgets

代码语言:javascript
复制
char str[100];
fgets( str, 100, input_result);
票数 0
EN

Stack Overflow用户

发布于 2019-06-15 12:30:51

在读取文件时,对hardcode的行数、列数和缓冲区数有很大的限制。这里有一种使用dynamic memory的更灵活的方法。

然而,输入文件并非没有假设:文件应该以换行符结尾,具有固定的列,没有格式错误,第一行是标题,等等。它还频繁地调用realloc,这在实践中不应该导致许多系统调用,但可以通过将容量加倍而不是增加容量来加快速度。这是一个概念的证明。

代码语言:javascript
复制
#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;
}

输出:

代码语言:javascript
复制
0.099601 82.921184 1.459357 1.576886 0.381672 0.250597 0.392030 12.918674 0.000000
0.199601 65.802794 2.895808 3.160080 0.764870 0.502196 0.785629 25.889022 0.000000
0.000000 99.971372 0.028628 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

如果文件更改为:

代码语言:javascript
复制
Caso Escp P1 P2 P3 P4 P5 P5+ Caos HCaos
Total 0.099601 82.921184 1.459357 1.576886
Biest 0.199601 65.802794 2.895808 3.160080
Mxxxxst 1.000000 99.971372 1.028628 2.000000
Mxxxxst 2.000000 19.971372 7.028628 3.000000
Mxxxxst 3.000000 29.971372 6.028628 5.000000
Mxxxxst 4.000000 29.971372 3.028628 6.000000

那么它仍然可以工作:

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56606169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档