⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calculator.c

📁 嵌入式linux下的一个高级计算器程序的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    calculator.c  by Dr. Gerhard Wanderer   (gerhard.wanderer@i-dail.de)    $Id: calculator.c,v 1.3 2002/12/17 15:31:55 gerhard Exp gerhard $    Subroutines to evaluate a string and calculate the contained formulas    =====================================================================    The evaluation is done recursively, working on the line from left to     right.     The subroutine "Calculator" is the main entry point and needs two    arguments:  the formula, which should be calculated and a structure    CALCFKT, which stores the local or user-defined variables.         The subroutine "Calculator" first checks, whether a function    definition is given (indicated by ":=" in the comandline). In this     case it creates a entry in the CalculatorFkt list and stores the    remainder of the line as the funtion definition and returns.    Otherwise it calls Calculator_Sub with local variables as working    variables for Calculator_Sub.     If the recursion ended or no recursion was necessary, the returned    result of Calculator_Sub is stored in the CalculatorHistory List for     future use.     ------------------    Calculator_Sub parses the commandline and divides the line into    subexpressions.     If it is called the first time for a certain command line     (istack == 0), it checks, whether the values should be stored in a     variable (this is indicated by the character "=". If this is the case,     it searches for this  variable or creates a new one.     Next it searches for the first operand and puts it on the stack    If it is called again, it expects the first character to be a operator    ("+", "-", "*", "/" or "^"). If none is found, "*" is assumed.     The operator is saved on the stack.    If the operator level is lower or equal the previouse one, the operand    stack is reduced.    Now the next operand is searched and put on the stack.    If the line ends, the stack is reduced and result is returned.    The operand search is divided into five actions:      - first it is checked, wether a sub-formula is given by surrounding        brackets "(", ")". If this is the case, the included substring is        isolated and the subroutine "Calculator" is called with this         substring, resulting in an recursion loop. The result of this        ip put on the stack.      - if no sub-formula is given, it checkes, whether a number is         given. This number is put on the stack      - if no number is give, i.e. the remaining string begins with a         character a..z or A..Z, if is looked up in the table of build         in funtions. Most of the build in functions require one argument,         which has to be provided in brackets after the function name         ("sin(3.2)"). The subroutine FindBrackets isolates the included         substring and calls the subroutine Calulator to evaluate this         substring and return the calculated value.      - if no build-in function is found, the list of user-defined         variables is examined. If one is found, it磗 value is copied to         the stack.      - if no user-defined variable is found, the list of user-defined         functions is examined. If one is found, the subroutine CalculateFkt        examines the parameter list and calculates the function with the        given arguments. The returned value is put on the stack.    --------------------------------    The Subroutine CalculateFkt examines the argument list given within    brackets. The arguments are separated by the character ";". Each    argument is calculated by calling the subroutine Calculator with    the argument parameters as the formula string and the global variables.     This means, that the user-defined variables can be used, when the     parameters are given as formulas. The results are stored in the     functions local variable list.     To calculate the function, Calculator is called with the funtion     definition as the formula an the local variable list.*///#include <ctype.h>#include <malloc.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#define _CALCULATOR_#include "calculator.h"// pre-definition of internal functionsdoubleFindBrackets(char *text, int *end, CALCFKT *cal);doubleFindDualParam(char *text, int *end, CALCFKT *cal, double *pa1);double Calculator_Sub (char *formel, double *NumStack, char *OpStack,                 char *OpLvlStack, int *iStack, CALCFKT *cal);char  *interncons[] = {"ANS", "PI"};#define   INTERNCONS  2char  *internfkt[] = {"LN",    "EXP",   "LG",     "LOG10", "LOG2", "LOG",  "ABS", "SQRT","ATAN2","SIGN",		      "AHSIN", "ASINH", "HASIN",  "ASIN",  "HSIN", "SINH", "SIN",		      "AHCOS", "ACOSH", "HACOS",  "ACOS",  "HCOS", "COSH", "COS",		      "AHTAN", "ATANH", "HATAN",  "ATAN",  "HTAN", "TANH", "TAN",		      "AHSEC", "ASECH", "HASEC",  "ASEC",  "HSEC", "SECH", "SEC",		      "AHCOT", "ACOTH", "HACOT",  "ACOT",  "HCOT", "COTH", "COT",		      "AHCSC", "ACSCH", "HACSC",  "ACSC",  "HCSC", "CSCH", "CSC",};int    internfktid[] = {0,      1,      2,         2,       3,      4,      5,     6,     7,      8,			9,      9,      9,        10,       11,     11,    12,			13,    13,     13,        14,       15,     15,    16,			17,    17,     17,        18,       19,     19,    20,			21,    21,     21,        22,       23,     23,    24,                        25,    25,     25,        26,       27,     27,    28,			29,    29,     29,        30,       31,     31,    32};#define   INTERNFKT (int) sizeof(internfktid)/sizeof(int)////voidInsertVariable(char *name, double var) {  int  iVar, i, ilast, ip;  iVar = -1;  for (i = 0; i < CalculatorFkt[0].Vars; i++)    if (strcmp(CalculatorFkt[0].Var[i].Name, name) == 0)       iVar = i;    if (iVar < 0) {// Variable does not exist    if (CalculatorFkt[0].Vars < CALCULATOR_VARS-1) {      // create new user-defined variable      CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Name = (char*) malloc(strlen(name)+1);      strcpy(CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Name, name);      iVar = CalculatorFkt[0].Vars;      CalculatorFkt[0].Vars++;    }    else {      // already 99 Variables uses; need to free the longest unused      ilast = CalculatorFkt[0].RefCnt;      ip    =  -1;      for (i = 0; i < CalculatorFkt[0].Vars; i++) {	if (CalculatorFkt[0].Var[i].Ref < ilast) {	  ip = i;	  ilast = CalculatorFkt[0].Var[i].Ref;	}      }      if (ip >= 0) {	iVar = ip;	free(CalculatorFkt[0].Var[ip].Name);	CalculatorFkt[0].Var[ip].Name = (char*) malloc(strlen(name)+1);	strcpy(CalculatorFkt[0].Var[ip].Name, name);      }      else {	return; // setting impossible      }    }  }  CalculatorFkt[0].RefCnt++;  CalculatorFkt[0].Var[iVar].Valu = var;  CalculatorFkt[0].Var[iVar].Ref = CalculatorFkt[0].RefCnt;}voidReadHistory (FILE *config){  char   inpline[256];  char  *ptr, *ptr2, *p1, *p2;  int i, mode, fktready;  mode  = 0;  ptr2 = NULL;  CalculatorFktAnz = 0;  // if a configuration file already exists, read in the content  if (config) {    while (!feof(config)) {      if (fgets(inpline, 256, config)) {	if (strstr(inpline, "[REF]") == inpline)  // last timestamp	  mode = 1;	else if (strstr(inpline, "[VAR]") == inpline)	  // the list of user-defined variables begins now	  mode = 2;	else if (strstr(inpline, "[HIST]") == inpline) {	  // the formula history list begins now	  mode = 3;	  ptr2 = NULL;	}	else if (strstr(inpline, "[FKT]") == inpline) {	  // the list of user-defined functions begins now	  mode = 4;	  ptr2 = NULL;	  CalculatorFktAnz = 0;	}	else if (strstr(inpline, "[VHIST]") == inpline)	  // the result (value) history list begins now	  mode = 5;	else {	  	  switch (mode) {	  case 1:  // REF	    if (strstr(inpline, "radian=")) {	      p1 = strchr(inpline, '=');	      sscanf(&p1[1], "%d", &CalculatorRad);	    } else if (strstr(inpline, "format=")) {	      p1 = strchr(inpline, '=');	      sscanf(&p1[1], "%d", &CalculatorFmt);	    } else if (strstr(inpline, "autoans=")) {	      p1 = strchr(inpline, '=');	      sscanf(&p1[1], "%d", &CalculatorAutoAns);	    } else if (strstr(inpline, "autohighlight=")) {	      p1 = strchr(inpline, '=');	      sscanf(&p1[1], "%d", &CalculatorAutoHighlight);	    } else  	      sscanf(inpline, "%d", &CalculatorFkt[0].RefCnt);	    break;	  case 2:  // read the list of userdefined variables	    // each line has three fields, separated by ";"	    //    1. field: name of variable            //    2. field: last value            //    3. timestamp	    // example: "AA;                20;1"	    ptr = strchr(inpline, ';');	    if (ptr) {	      // only read, if it磗 a valid entry	      ptr[0] = 0;	      // store the name of the variable	      CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Name = 		(char*) malloc (strlen(inpline)+1);	      strcpy(CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Name, 		     inpline);	      ptr++;	      ptr2 = strchr(ptr, ';');	      // read the value and the timestamp	      if(ptr2) {		ptr2[0] = 0;		sscanf(ptr, "%lf", 		       &CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Valu);		ptr2++;		sscanf(ptr2, "%d", 		       &CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Ref);	      }	      else {		CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Valu = 0;		CalculatorFkt[0].Var[CalculatorFkt[0].Vars].Ref  = 0;	      }	      CalculatorFkt[0].Vars++;	    }	    break;	  case 3:  // read the formula history list. Formulas may be longer	    // than the maximum linelength of 255 character. In this case            // the formula is written to many lines with the character "\ "            // at the end of all lines except the last (continuation 	    // character). 	    i = strlen(inpline);	    // remove unwanted blanks	    while((i > 0) && ((inpline[i] <= ' ') || ((unsigned)inpline[i] >= 0x80)))	      {inpline[i] = 0; i--;}	    if (strlen(inpline)) {	      // if there is already a part of the formula read, append                // the next part	      if (ptr2) {		ptr = (char*) realloc(ptr2, 				      strlen(inpline)+strlen(ptr2)+1);		strcat(ptr, inpline);	      }	      else { // store this part		ptr = (char*) malloc(strlen(inpline)+1);		strcpy(ptr, inpline);	      }	      	      // will the next line belong to this line?	      if (ptr[strlen(ptr)-1] == '\\') {		// remember the current part for continuation		ptr2 = ptr;		ptr[strlen(ptr)-1] = 0;	      }	      else {		// if complete add the formula to the history list		if (CalculatorCmdHistoryAnz < CALCULATOR_FHISTORY) {		  CalculatorCmdHistory[CalculatorCmdHistoryAnz] = ptr;		  CalculatorCmdHistoryAnz++;		}		ptr2 = NULL;	      }	    }	    break;	  case 4: // read the user-defined functions	    // the first line containes the function name and the number of            // parameters; the names of the parameters follow, each on a             // separate line; after the parameters the function definition             // follows, if necessary on several lines, marked with the             // continuation character.            // The name of the function as well as the names of the             // parameters are surrounded by the characters "<" and ">".	    	    CalculatorFktAnz++;	    fktready = 0;	    // isolate function name	    p1 = strchr(inpline, '<');	    p2 = strchr(inpline, '>');	    p1++;	    p2[0] = 0;	    p2++;	    CalculatorFkt[CalculatorFktAnz].Name = 	      (char*) malloc(strlen(p1)+1);	    strcpy(CalculatorFkt[CalculatorFktAnz].Name, p1);	    // get number of paramters	    sscanf (p2, "%d", &CalculatorFkt[CalculatorFktAnz].Vars);	    // read in the paramter names	    for (i = 0; i < CalculatorFkt[CalculatorFktAnz].Vars; i++) {	      fgets(inpline, 256, config);	      p1 = strchr(inpline, '<');	      p2 = strchr(inpline, '>');	      p1++;	      p2[0] = 0;	      CalculatorFkt[CalculatorFktAnz].Var[i].Name = 		(char*) malloc(strlen(p1)+1);	      strcpy(CalculatorFkt[CalculatorFktAnz].Var[i].Name, p1);	    }	    ptr2 = NULL;	    // read in the function formula	    while (!fktready) {	      fgets(inpline, 256, config);	      i = strlen(inpline);	      // remove blanks at end of line	      while((i > 0) && (inpline[i] <= ' ')) {inpline[i] = 0; i--;}	      if (ptr2) {		// append new text to previous		ptr = (char*) realloc(ptr2, 				      strlen(inpline)+strlen(ptr2)+1);		strcat(ptr, inpline);	      }	      else {		// begining of definition 		ptr = (char*) malloc(strlen(inpline)+1);		strcpy(ptr, inpline);	      }	      // check for continuation line	      if (ptr[strlen(ptr)-1] == '\\') {		// save current text for appening of continuation line		ptr2 = ptr;		ptr[strlen(ptr)-1] = 0;	      }	      else {		// save function definition and signal successful 		// definition		fktready = 1;		CalculatorFkt[CalculatorFktAnz].Def = ptr;	      }	    }	    break;	  case 5: // read Result History	    if (CalculatorHistCnt < CALCULATOR_HISTORY) {	      sscanf(inpline, "%lf", 		     &CalculatorHistory[CalculatorHistCnt]);	      CalculatorHistCnt++;	    }	    break;	  }	}      }    }  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -