2016-12-06 6 views
2

私は数値積分プログラムを持っており、テキストファイルから関数を読み込んで、後置アルゴリズムで関数を計算したいと考えています。あなただけの魔法から行くことができない、まあ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

:私の問題は、私は、ファイルからsinlogなどを読んで、私は多分このようなstrtol()機能を使用array.For番号にそれらを置くことができるか、です文字列sinに正弦関数を計算します。それを行うためのコードを書く必要があります。

入力をトークンに分割することをお勧めします(おそらくループ内でstrtok()を使用するだけです)。次に、各トークンを検査します。

数字の場合は、数字をスタックにプッシュします(関数/演算子は後置であるため、スタックが必要です)。

文字列(関数名)の場合は、ハードコードされたテーブルまたはif -seriesで検索し、評価します。

何かのように:これだけは解決することができる方法の概要を与えることを意図し、これは非常に荒れていることを

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

あなたには2つの質問があります。ワン:私は罪を読み取ることができますどのように

、ファイル

等からログイン他:

は、どのように私は...配列にそれらを置くことができ


最初の質問:ファイルからの読み込み。 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); 
     } 
    } 
} 

2番目の質問:アレイに追加します。 「操作」のための4つの可能な種類がありますが、ここで

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

- それは数、単項機能(のようなsin)、バイナリ機能(+のような)または独立にすることができます。私はtagged unionを使用することをお勧めします変数xoperationにトークンpを変換するには

:ここ

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

2つの数値を追加しますplus機能。標準ライブラリは、(それが持っている、sinとは違って)それを持っていないので、私は自分でそれを定義する必要があります。

struct operation my_array[1000]; 

:あなたはoperationオブジェクトの配列を持っている場合、

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

を最後に

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です:あなたは配列にオブジェクトを追加することができます配列を使用して、xの任意の値のエンコードされた関数の値を計算します。関数の配列としてコード化された関数があるので、計算自体は簡単になります。一時的な値のスタックを作成し、各操作を適用するだけです。

+0

「x」とどうすればいいですか?例:sin(x)5 * – femix

+0

私の答えが更新されました。ところで、 'x sin 5 *'のように関数を後置式でエンコードしたいかもしれません。 – anatolyg

関連する問題