【问题标题】:Input in specific format (matrix)以特定格式输入(矩阵)
【发布时间】:2018-05-07 14:14:37
【问题描述】:

我的作业输入有问题。在标准输入上,我会得到一个特别格式化的输入。

在第一行,将有 2 个整数,确定矩阵的大小(行和列)。后面的所有行代表矩阵的行。

我本质上想做一些类似 getline() 的事情,但我不想使用 getline()。事实上我不能,它在作业中被禁止。因此,我必须按 int 扫描 int(或者我猜是按 char 扫描)。这里的问题是我需要它是防弹的(几乎)。至少可以防伪。

我在想象一个大的 while 循环,它一直持续到 EOF 和另一个循环(也许?),它总是读取一行,将它保存到我分配的矩阵并继续到下一个。我知道我应该检查“\n”,但我今天有点缺乏思考解决方案的能力。

这是我正在使用的:我的矩阵是一个结构。

struct Matrix{
    int nrows;
    int ncols;
    int** matrix;
};

然后我就有了多种功能。

为特定大小的矩阵动态分配空间的函数:

struct Matrix init_matrix(int r, int c)
{
    struct Matrix mat;
    mat.nrows = r;
    mat.ncols = c;
    mat.matrix = calloc(r, sizeof(int *));
    for(int i = 0; i < r; ++i)
    {
        *(mat.matrix+i) = calloc(c, sizeof(int));
    }

    return mat;
}

释放先前分配空间的函数:

void free_matrix(struct Matrix mat)
{   
    int top = mat.nrows;
    for(int i = 0; i < top; ++i)
    {
        free(mat.matrix[i]);
    }
    free(mat.matrix);
}

这两个功能工作得很好。

现在我正在尝试创建一个函数 create_matrix(void)(至少我认为它不应该接受任何参数),它将读取我应该接收的输入,例如:

3 3
1 2 3
4 5 6
7 8 9

当函数读取输入时,它可以判断输入是否不正确或格式不正确,并以相应的退出值(如 100 fe)退出程序如果输入正确且格式正确,则调用 init_matrix( ) 然后将输入保存到矩阵中。

为了您更深入的了解:我应该收到的全部输入是: 矩阵A(如上,第一行的大小,后行的值) 操作 (+,-,*) 矩阵B

然后执行操作(A*B、A+B 等)。我正在尝试将大多数东西变成函数,所以 main 会很简单,f.e.

int main(int argc, char *argv[])
{
    struct Matrix mat1 = create_matrix();
    char operation = get_operation();
    struct Matrix mat2 = create_matrix();
    struct Matrix result = compute(mat1,mat2, operation);
    return 0;
}

如果你明白我的话。问题是我想让程序足够复杂,以便以后可以编辑它以处理比两个更大的矩阵序列(最多 100 个)。现在我可以用一种肮脏的方式来做,通过一次操作让它适用于两个矩阵,但这不是我真正想要的。

【问题讨论】:

  • 那么问题是什么?到目前为止,您的计划看起来不错。
  • create_matrix 函数结构。真的无法想象如何首先扫描大小值并检查它们是否在第一行,然后再进行更大的扫描以完成其余的工作。我有点怀疑会有 2 次扫描,但这就是我所能想象的。
  • 如果您不能使用getline(),请使用fgets() 读取行。如果您也不能使用它,请为getline() 编写自己的代理;这并不难。 scanf() 函数会放弃跳过空白,包括新行,并且不能简单地用于确保数据在正确的行上。一旦你有一行要处理,就在循环中使用sscanf()
  • 听起来你想让compute 处理任意数量的矩阵。您可以使用 stdarg.h: struct Matrix compute(char, struct Matrix, ...); 来使用可变参数函数。
  • 您对create_matrix() 的设计可能不是最佳的。您需要传入文件流或文件名,以便它知道从哪里获取数据。依靠全局变量来传达这些信息是很糟糕的。如果它会从标准输入中读取,那么也许是可以的,但它不是很灵活;最好提供名称或要读取的流作为create_matrix() 的参数。剩下的就是基本的文件读取操作——繁琐多于困难。

标签: c matrix dynamic-allocation formatted-input


【解决方案1】:

嗯,这就是我解决它的方法。有用。它不是接近完美的地方,但它可以工作,上传系统接受它并给它全额积分,所以我很满意。

struct Matrix read_matrix(FILE *fp)
{
    struct Matrix mat;
    //FIRST LINE
    int ch;
    int i = 0;
    int n = 20;
    char* line = calloc(n,sizeof(char));
    while((ch = fgetc(fp)) != EOF && ch != '\n')
    {
        *(line + i++) = ch;
    }
    *(line + n-1) = '\0';
    int r,c;
    int k = sscanf(line,"%d %d", &r, &c);
    if(k != 2)
    {
        fprintf(stderr, "Error: Chybny vstup!\n");
        exit(100);
    } 
    free(line);
    //MATRIX
    line = calloc(c, sizeof(int));
    mat = init_matrix(r, c);
    i = 0;
    r = 0;
    while(r < mat.nrows && (ch = fgetc(fp)))
    {
        if(ch == '\n' || ch == EOF)
        {
            *(line + i) = '\0';
            int offset;
            char *data = line;
            for(int j = 0; j < mat.ncols; ++j)
            {
                int d = sscanf(data, " %d%n", &mat.matrix[r][j], &offset);
                if(d != 1){
                    fprintf(stderr, "Error: Chybny vstup!\n");
                    exit(100);
                }
                data += offset;
            }
            i = 0;
            ++r;
            if(ch == EOF){ 
                break;
            }
        } else
        {
            *(line + i++) = ch;
        }
    }
    free(line);
    return mat;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多