简体   繁体   中英

Reading function from txt file in C?

I have numerical integration program, and I want to read the function from text file and calculate the function with postfix algorithm. My problem is,how can I read sin , log etc. from file and put them into array.For numbers I maybe use the strtol() function like this :

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

Well, you can't just magically go from the string sin to calculating the sine function. You have to write code to do that.

I'd recommend splitting the input into tokens (perhaps just using strtok() in a loop), then inspecting each token.

For numbers, push the numbers onto your stack (I assume you want a stack since you mention the functions/operators being postfix).

For strings (names of functions), look them up in a hardcoded table or if -series and do the evaluation.

Something like:

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

Note that this is very rough, only intended to give an outline of how this can be solved.

You have two questions. One:

how can I read sin,log etc. from file

The other:

how can I ... put them into array


First question: reading from file. Use strtok to separate a line of text into "words". Use strcmp to examine the function name.

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

Second question: adding to an array. I recommend using a 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
    };
};

Here, there are 4 possible types for an "operation" - it can be a number, an unary function (like sin ), a binary function (like + ) or an independent variable x .

To convert a token p to an 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;
    }
    ...
}

Here the function plus adds two numbers. Standard library doesn't have it (unlike sin , which it has), so I have to define it by myself:

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

Finally, if you have an array of operation objects:

struct operation my_array[1000];

you can add objects to the array:

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
}

The main part of the program is using the array to calculate the value of the encoded function for any value of x . Now that you have your function encoded as an array of operations, the calculation itself will be easy. Just make a temporary stack of values, and apply each operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM