如何从C中的文本文件填充矩阵(结构)?

德拉科里斯·乌里莱斯(Drakoris Urileth)

我正在尝试制作一个程序,该程序可以读取文本文件并在结构体内部填充矩阵,但是我遇到了一些问题。

#include <stdio.h>

#define MAX 100

typedef struct {
    int matrixgrafh[MAX][MAX];
} matrix;

int LoadMatrix(matrix* m);

main()
{
    int j,k;
    matrix m;

    LoadMatrix(&m);
    for(j = 0;j < 20;j++)
    {
        for(k = 0;k < 20;k++)
        {
            printf("%d",m.matrixgrafh[j][k]);
        }
    }
}

int LoadMatrix(matrix* m)
{
    FILE *stuff;
    int j,k;
    char c;

    if((stuff=fopen("matrix.txt","r"))==NULL)
    {
        printf("File missing...");
        exit(1);
    }
    while (!feof(stuff))
    {
         do
         {
            c = fgetc(stuff);
            if (c == '1' || c == '0' && c != '\n' && !feof(stuff))
            //corrected c == '1' && c == '0' to c == '1' || c == '0'
            {
                for(j = 0;j < 20;j++)
                {
                    for(k = 0;k < 20;k++)
                    {
                        m->matrixgrafh[j][k] = c;
                    }
                }
            }
         } while (!feof(stuff));
    }
    return m->matrixgrafh;
}

这个想法是从文本文件中读取一个矩阵,如下所示:

1 1 1

1 0 1

0 0 1

并以相同的方式填充矩阵

问题是矩阵未正确填充,显示为494949494949 ...我期望循环遍历该矩阵,并且该矩阵包含与文本文件相同的值。

戴维·C·兰金

您首先应该看一个问题,为什么“ while(!feof(file))”总是错误的?虽然不会直接造成问题,但由于其造成的陷阱,您将希望避免采用这种方法从文件中读取文本。

接下来,当您从文件中读取数据行时,通常最好一次读取一行。虽然一次读取一个字符没什么问题,但是通过面向字符的输入,由于需要检查每个字符,找到每个数字的开头,将数字临时缓冲在一个数字中,因此读取数字时的代码将明显更长。以null终止的字符串,然后将缓冲的数字转换为数字(即使使用'0'和'1',它们仍必须从字符转换为数字)

也就是说,面向输入的主要工具fgetsgetline(每个都有优点和缺点)。对于这样的简单任务,fgets绰绰有余。那么你读了一行,那又如何呢?您必须将行分隔为包含每个数字的数字的字符串,然后将字符串转换为数字。C库具有专门为此任务创建的工具。查看strtol(字符串到长整数),strtoul(无符号长整数),strtof(浮点数)等。

每个strtoX函数都使用一个指向要转换的字符串的指针,以及第二个指针(an endptr),该指针将用刚转换的数字后面的字符串中的一个字符填充地址(整数函数也将base用作参数,以允许转换为基数10、16等。)

为什么endptr如此重要?它允许您处理行中的数字(包含未知数量的数字),依次转换每个数字,直到到达行尾。这些strtoX功能提供了良好的错误检测和报告功能,使您可以处理从文件中读取的行,并在结束时停止操作(以及报告转换失败的情况)

面向行的输入与(在您的情况下)fgets一起使用strtol,将允许您读取文件中的每一行并将文件中的每个数字转换为结构中数组中的数字。

我不知道是否可以添加到您的结构中,但是使用结构体来保存数组会带来麻烦,当然也要存储文件的数目rowscols从文件中读取数据是有道理的将结构传递给函数,进行打印等操作时,可以通过多种方式简化工作。

typedef struct {
    int matrixgrafh[MAX][MAX];
    size_t rows;
    size_t cols;
} matrix;

是你所需要的全部。

现在,将其放到一个工作示例中。我将strtol调用放在函数中只是为了避免因LoadMatrix错误检查等而使逻辑混乱。等等。我还把您现有的代码留在了函数中,但是注释了一下,以便您可以看到不同之处:

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

#define MAX 100
#define MAXLN 256

typedef struct {
    int matrixgrafh[MAX][MAX];
    size_t rows;
    size_t cols;
} matrix;

int LoadMatrix (matrix * m);
long xstrtol (char *p, char **ep, int base);

int main (void)
{
    size_t j, k;
    matrix m;

    if (LoadMatrix (&m) == -1) {
        fprintf (stderr, "error: LoadMatrix failed.\n");
        return 1;
    }

    printf ("\nThe %zux%zu matrix read from file is:\n\n", m.rows, m.cols);    
    for (j = 0; j < m.rows; j++) {
        char *pad = " [ "; \
        for (k = 0; k < m.cols; k++) {
            printf ("%s%2d", pad, m.matrixgrafh[j][k]);
            pad = ", ";
        }
        printf (" ]\n");
    }
    putchar ('\n');

    return 0;
}

int LoadMatrix (matrix *m)
{
    FILE *stuff;
    char line[MAXLN] = {0};     /* line buffer */
    char *p, *ep;     /* pointers for strtol   */
    size_t row = 0;   /* simple row counter    */
    // char c;

    if ((stuff = fopen ("matrix.txt", "r")) == NULL) {
        printf ("File missing..."); /* should be fprintf */
        exit (1);
    }

    while (fgets (line, MAXLN, stuff)) /* read each line in file */
    {
        size_t col = 0;    /* initialize variables for each row */
        p = ep = line;
        errno = 0;

        /* skip to first digit in line */
        while (*p && *p != '-' && (*p < '0' || *p > '9')) p++;

        while (errno == 0)
        {   /* read each number in row */
            m->matrixgrafh[row][col++] = (int)xstrtol (p, &ep, 10);

            if (col == MAX) { /* check col against MAX */
                fprintf (stderr, "LoadMatrix() error: MAX columns reached.\n");
                break;
            }

            /* skip to next number */
            while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
            if (*ep) p = ep;
            else break;
        }

        if (row == 0) m->cols = col;    /* set the number of colums in each row */
        if (col != m->cols) {           /* validate each row against first      */
            fprintf (stderr, "LoadMatrix() error: invalid number of columns, row '%zu'.\n",
                    row);
            fclose (stuff);
            return -1;
        }
        row++;

        if (row == MAX) { /* check col against MAX */
            fprintf (stderr, "LoadMatrix() error: MAX rows reached.\n");
            break;
        }
    }

    fclose (stuff);

    m->rows = row;

    return 0;

    /* see why 'while (!feof (file))' is always wrong */
    // while (!feof (stuff)) {
    //     do {
    //         c = fgetc (stuff);
    //         if (c == '1' || c == '0' && c != '\n' && !feof (stuff))
    //             //corrected c == '1' && c == '0' to c == '1' || c == '0'
    //         {
    //             for (j = 0; j < 20; j++) {
    //                 for (k = 0; k < 20; k++) {
    //                     m->matrixgrafh[j][k] = c;
    //                 }
    //             }
    //         }
    //     } while (!feof (stuff));
    // }
    // return m->matrixgrafh;
}

/** a simple strtol implementation with error checking.
 *  any failed conversion will cause program exit. Adjust
 *  response to failed conversion as required.
 */
long xstrtol (char *p, char **ep, int base)
{
    errno = 0;

    long tmp = strtol (p, ep, base);

    /* Check for various possible errors */
    if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
        (errno != 0 && tmp == 0)) {
        perror ("strtol");
        exit (EXIT_FAILURE);
    }

    if (*ep == p) {
        fprintf (stderr, "No digits were found\n");
        exit (EXIT_FAILURE);
    }

    return tmp;
}

看一下,如果您有任何问题,请告诉我。所使用的输入,编译字符串和您应期望的输出如下:

输入

$ cat matrix.txt
1 1 1
1 0 1
0 0 1

编译

gcc -Wall -Wextra -o bin/matrix_struct matrix_struct.c

输出

$ ./bin/matrix_struct

The 3x3 matrix read from file is:

 [  1,  1,  1 ]
 [  1,  0,  1 ]
 [  0,  0,  1 ]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在文本文件中填充方法的输出

来自分类Dev

如何从R中的文本文件读取矩阵

来自分类Dev

从Matlab中的文本文件加载大矩阵

来自分类Dev

将文本文件导入为numpy中的矩阵

来自分类Dev

从C中的文本文件读取矩阵

来自分类Dev

从Julia中的文本文件读取数据矩阵

来自分类Dev

从文本文件构建字符矩阵(C ++)

来自分类Dev

如何将结构松散的文本文件中的表读入R中的数据框?

来自分类Dev

如何从文本文件中除数?

来自分类Dev

从文本文件C ++填充对象

来自分类Dev

将文本文件中的矩阵数据存储在c中的多维数组中

来自分类Dev

文本文件中的相关矩阵

来自分类Dev

在C ++中,如何提取文本文件的FileFilePath

来自分类Dev

如何在文本文件中填充方法的输出

来自分类Dev

如何从C ++中的文本文件读入?

来自分类Dev

如何从R中的文本文件读取矩阵

来自分类Dev

如何在python中打开文本文件作为字符矩阵?

来自分类Dev

如何从C#中的文本文件获取数据

来自分类Dev

如何在文本文件中编写矩阵?

来自分类Dev

R:删除存储在文本文件中的矩阵的空格

来自分类Dev

如何从文本文件访问矩阵的所需部分?

来自分类Dev

无法从C中的文本文件读取结构

来自分类Dev

如何在C#中解析文本文件?

来自分类Dev

从 C++ 中的文本文件读/写结构

来自分类Dev

我如何从文本文件中输入文本 (c)

来自分类Dev

在 Clojure 中,如何从文本文件中读取分层数据结构?

来自分类Dev

在python中读取矩阵文本文件

来自分类Dev

如何将矩阵保存在文本文件中

来自分类Dev

如何从我创建的文本文件中读取结构?