2016-12-06 34 views
2

我有数值积分程序,我想从文本文件中读取函数,并用后缀算法计算函数。我的问题是,如何从文件中读取sinlog等,并把它们放到array.For号我也许使用strtol()功能是这样的:从C中的txt文件读取函数?

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++; 
     } 
    } 
} 
+0

我无法解析您的示例字符串。函数应该以中缀格式('2 * sin(x * pi)')还是后缀('x pi sin 2 mult')给出? –

+0

示例字符串仅用于读取数字。该函数应该以后缀格式给出。 – femix

+0

你在记事本中写你的代码吗?使用一些IDE! –

回答

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 ... 
} 

注意,这是很粗糙的,只打算给这如何可以解决的轮廓。

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 
} 

该计划的主要部分是USI ng数组计算任何值为x的编码函数的值。现在你已经将你的函数编码为一个操作数组,计算本身将很容易。只需创建一个临时堆栈值并应用每个操作。

+0

我该怎么处理'x'?例如:sin(x)5 * – femix

+0

更新了我的答案。顺便说一句,你可能想用后缀的方式编码你的函数,比如'x sin 5 *' - 代码更容易 – anatolyg