C - 读取和解析方法未获得第二行输入

时间:2016-09-12 05:50:27

标签: c parsing matrix io strtok

我正在编写一个程序来处理我存储在Matrix结构中的方程组。目的是以

格式读取一行
1 2 3, 2 3 4

并且相当于

  

x + 2y = 3

     

2x + 3y = 4

目前只存储

  

x + 2y = 3

进入我的矩阵。

我有一种蓝图,我通常用它来解析C中的输入但是我不得不偏离它以符合这个分配,我猜测内循环的问题是什么?标记化过程,即破坏原始输入。

相关代码:

#define delims " \t\r\n"

Matrix createMatrix()
{
    Matrix m = malloc(sizeof(Matrix));

    char *input, c;
    int len = 0, max = 1;

    char *row, *coeff;

    int rows = 0, cols;
    bool set = false;

    printf("\n: ");

    input = malloc(max);

    // get input from user
    while ((c = getc(stdin)) != '\0' && c != '\n')
    {
        input[len++] = c;

        if (len == max)
        {
            input = realloc(input, 2*max);
            max *= 2;
        }
    }

    // parse input into equation by (,) delimiter
    row = strtok(input, ",");

    do
    {
        cols = 0;

        // parse equation into coefficients by space delimiter
        coeff = strtok(row, delims);
        setCoeff(m, rows, cols++, atoi(coeff) / 1.0);

        while ((coeff = strtok(NULL, delims)) != NULL)
        {
            setCoeff(m, rows, cols++, atoi(coeff) / 1.0);
        }

        coeff = strtok(NULL,delims);

        rows++;

        if (!set)
        {
            setCols(m, cols);
            set = true;
        }
        else
            assert(cols == m->cols);

    }
    while ((row = strtok(NULL, ",")) != NULL);

    row = strtok(NULL, ",");

    setRows(m, rows);

    return m;
}

Matrix.h

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

#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED

typedef struct Matrix
{
    int rows;
    int cols;
    double coeff[26][27];
} *Matrix;

void setRows(Matrix m, int r);
void setCols(Matrix m, int c);

void setCoeff(Matrix m, int row, int col, double val);

#endif // MATRIX_H_INCLUDED

Matrix.c

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

#include "Matrix.h"

void setRows(Matrix m, int r)
{
    m->rows = r;
}

void setCols(Matrix m, int c)
{
    m->cols = c;
}

void setCoeff(Matrix m, int row, int col, double val)
{
    m->coeff[row][col] = val;
}

2 个答案:

答案 0 :(得分:3)

您正在使用strtok两次:一次读取逗号分隔数据,然后在内部读取值。您的while条件将使用给它的最新指针,即值读取器,因此它无法为您找到任何行。

您必须首先读取行,然后读取值,或者为这些行使用单独的方法,而不是strtok

答案 1 :(得分:2)

strtok维持内部状态以跟踪其遗留的位置。这就是为什么你应该在第一次调用它时传递原始字符串,但在后续调用时用NULL调用它。您正在尝试将独立呼叫交错到strtok,因此无法在第一次呼叫和后续呼叫之间进行正确区分。

您可以尝试使用strtok_r(POSIX指定的可重入版本strtok不依赖于全局状态,从而避免此问题;在Windows上,等效函数为{ {1}})或strtok_s如果您的平台支持它们;两者都不是标准C的一部分。

如果您需要可移植性,则需要重新构建代码,以便分别执行解析阶段:首先完全解析所有strsep - 分隔的标记,跟踪结果,然后作为第二阶段,解析',' - 以前每个结果中的分隔标记。