从C中的txt文件读取函数?

时间:2016-12-06 10:23:28

标签: c

我有数值集成程序,我想从文本文件中读取函数并使用后缀算法计算函数。我的问题是,如何从文件中读取sinlog等并将它们放入数组中。对于数字,我可以使用strtol()函数,如下所示:

int main(){
    int i;
    char *str = "ab234 56 cid*(s349*(20kd", *p = str;
    while (*p) { 
        if (isdigit(*p)) { 
            long val = strtol(p, &p, 10); 
            printf("%ld\n", val);
        } else { 
            p++;
        }
    }
}

2 个答案:

答案 0 :(得分:3)

嗯,你不能神奇地从字符串sin转到计算正弦函数。你必须编写代码才能做到这一点。

我建议将输入拆分为令牌(可能只是在循环中使用strtok()),然后检查每个令牌。

对于数字,将数字推入堆栈(我假设你想要一个堆栈,因为你提到函数/运算符是后缀)。

对于字符串(函数名称),请在硬编码表或if - 系列中查找它们并进行评估。

类似的东西:

char **tokens = ... // NULL-terminated list of input tokens
int i = 0;
while(tokens[i] != NULL)
{
  if(isdigit(tokens[i][0]))
  {
    stack_push(strtol(token, NULL, 10));
  }
  else if(strcmp(tokens[i], "sin") == 0)
  {
    stack_push(sin(stack_pop()));
  }
  else if ...
}

请注意,这非常粗略,只是为了概述如何解决这个问题。

答案 1 :(得分:0)

你有两个问题。之一:

  

如何从文件中读取罪,记录等

另一个:

  

我怎么能......将它们放入数组

第一个问题:从文件中读取。使用strtok将一行文字分隔为"单词"。使用strcmp检查函数名称。

int main(){
    char str[] = "2 3 +";
    char *p;
    for (p = strtok(str, " "); p != NULL; p = strtok(NULL, " ")) {
        if (isdigit(*p)) { // it's a number
            long val = strtol(p, &p, 10); 
            printf("%ld\n", val);
        } else { // it's a name of a function
            if (strcmp(p, "+") == 0)
                puts("Add");
            else if (strcmp(p, "-") == 0)
                puts("Subtract");
            else if (strcmp(p, "sin") == 0)
                puts("Sine");
            else if (strcmp(p, "log") == 0)
                puts("Logarithm");
            else if ...
            ...
            else
                fputs("Error!", stderr);
        }
    }
}

第二个问题:添加到数组。我建议使用tagged union

enum type {CONSTANT, UNARY_FUNCTION, BINARY_FUNCTION, X};

struct operation
{
    enum type type;
    union {
        double val;
        double (*func1)(double); // a pointer to a function with 1 argument
        double (*func2)(double, double); // a pointer to a function with 2 arguments
    };
};

这里,"操作有4种可能的类型" - 它可以是数字,一元函数(如sin),二元函数(如+)或独立变量x

将令牌p转换为operation

char *p;
struct operation o;
...
if (isdigit(*p)) { // it's a number
    o.type = CONSTANT;
    o.val = strtol(p, &p, 10); 
} else { // it's a name of a function or "x"
    if (strcmp(p, "x") == 0)
    {
        o.type = X;
    }
    else if (strcmp(p, "+") == 0)
    {
        o.type = BINARY_FUNCTION;
        o.func2 = plus;
    }
    else if (strcmp(p, "sin") == 0)
    {
        o.type = UNARY_FUNCTION;
        o.func1 = sin;
    }
    else if (strcmp(p, "log") == 0)
    {
        o.type = UNARY_FUNCTION;
        o.func1 = log;
    }
    ...
}

此处函数plus添加两个数字。标准库没有它(与sin不同,所以我必须自己定义它:

double plus(double x, double y) {return x + y;}

最后,如果你有一组operation个对象:

struct operation my_array[1000];

您可以将对象添加到数组中:

struct operation my_array[1000];
size_t my_array_size = 0;

for (...)
{
    ... // parse input file
    struct operation o;
    ... // parse individual token and convert it to an "operation"
    my_array[my_array_size++] = o; // add to the array
}

程序的主要部分是使用数组计算任何x值的编码函数的值。现在您已将函数编码为操作数组,计算本身将很容易。只需制作一组临时值,然后应用每个操作。