В настоящее время я пишу код, который вводит функцию в виде строки от пользователя, преобразует ее в постфиксное выражение, затем преобразует ее в инфиксную, а затем оценивает выражение.
Работа еще продолжается, но в процессе я столкнулся с проблемой. Программа работает только в том случае, если число представляет собой однозначное целое число. Например, если коэффициент равен 50 или 1,4, это выдаст мне ошибку.
Я попробовал пару вещей, но каждый раз выдает ошибку.
Я попытался разделить каждое целое число отдельно, а затем перегруппировать их:
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
typedef struct token{
int type;
int value;
double value1;
int trig;
int precedance;
struct token *next;
} token;
typedef struct {
double items[200];
int top;
//double top1;
struct Stack *previous;
} Stack;
void printStack(Stack *s) {
printf("Stack: ");
for (int i = 0; i <= s->top; i++) {
if (isdigit(s->items[i])){
printf("%d ", s->items[i]);
}else{
printf("%c ", s->items[i]);
}}
printf("\n");
}
double evaluate_postfix(Stack *postfix, double* x) {
Stack eval_stack;
initialize(&eval_stack);
for (int i = 0; i <= postfix->top; i++) {
char token = postfix->items[i];
if (isdigit(token)) {
j = 1;
double tmp = token - '0';
while (isdigit(postfix->items[i + j])) {
tmp = tmp * 10 + (postfix->items[i +j] - '0');
j++;
}
i = i + j -1;
push(&eval_stack, tmp); // Convert char to int
..}
void infix_to_postfix_and_evaluate() {
Stack infixtmp, infix;
initialize(&infixtmp);
initialize(&infix);
token *tmp = head;
while (tmp != NULL) {
switch (tmp->type) {
case T_NUMBER:
push(&infix, tmp->value1 + '0'); // Convert int to char
break;
...}
void define_type() {
int j = 0; // Start j from 0 to handle the initial digit within the loop
if (isdigit(Function[i])) {
nexttoken->type = T_NUMBER;
nexttoken->value1 = Function[i] - '0';
}
Я также попробовал сначала сгруппировать их, но это тоже не работает...
void define_type(){
int j = 1;
if (isdigit(Function[i])) {
nexttoken->type = T_NUMBER;
nexttoken->value = Function[i] - '0';
while(isdigit(Function[i + j])) {
nexttoken->value = nexttoken->value * 10 + (Function[i + j] - '0');
j++;
}
i = i+j-1;
Вам следует преобразовать все числовые строки в их внутренний тип, прежде чем помещать их в стек. Это позволило бы использовать более одной цифры, а также обрабатывать типы с плавающей запятой. Используйте atoi, atof и т. д. функции библиотеки C, чтобы помочь вам.





Я не уверен, почему вы помещаете символы в массив двойных значений.
Если я перебираю массив символов, например:
void DoParse(char *pszFormula, unsigned nLength)
{
float fNum = -1;
for (unsigned i = 0; i < nLength; i++)
{
if ((fNum >= 0) && !isdigit(pszFormula[i]))
{
printf("Fnum: %f\n", fNum);
fNum = -1;
}
switch(pszFormula[i])
{
case '+':
case '-':
case '*':
case '/':
printf("Found operator %c\n", pszFormula[i]);
break;
default:
if (isdigit(pszFormula[i]))
{
fNum = (fNum >= 0 ? fNum * 10 : 0) + (pszFormula[i] - '0');
}
break;
}
}
if (fNum >= 0)
{
printf("Last fNum: %f\n",fNum);
}
}
Ввод 103+34*26 дает мне:
Fnum: 103.000000
Found operator +
Fnum: 34.000000
Found operator *
Last fNum: 26.000000
Ввод 43-64/6 дает мне:
Fnum: 43.000000
Found operator -
Fnum: 64.000000
Found operator /
Last fNum: 6.000000
Если я хочу поддерживать нецелочисленные параметры, мне нужно atof как предложил OldBoy.
void DoParse(char *pszFormula, unsigned nLength)
{
char szNum[12];
memset(szNum, 0, sizeof(szNum));
for (unsigned i = 0; i < nLength; i++)
{
switch(pszFormula[i])
{
case '+':
case '-':
case '*':
case '/':
if (*szNum && !isdigit(pszFormula[i]))
{
float f = atof(szNum);
printf("Found a number: %f\n", f);
/* purge buffer */
memset(szNum, 0, sizeof(szNum));
}
printf("Found operator %c\n", pszFormula[i]);
break;
case '.': /* append point to num buffer */
szNum[strlen(szNum)] = pszFormula[i];
break;
default:
if (isdigit(pszFormula[i]))
{ /* append digit to num buffer */
szNum[strlen(szNum)] = pszFormula[i];
}
break;
}
}
if (*szNum)
{
float f = atof(szNum);
printf("Found last number: %f\n", f);
}
}
Ввод типа 94.3+43.4/42 теперь дает:
Found a number: 94.300003
Found operator +
Found a number: 43.400002
Found operator /
Found last number: 42.000000
Вы также можете попробовать использовать strtok или sscanf.
Лучшее предложение для отладки вашего метода define_type — заставить его принимать входной параметр, а не использовать глобальную переменную. Таким образом, вы сможете быстро протестировать более широкий спектр струн. Начните с простого целочисленного параметра, за которым следует десятичная дробь, а затем постепенно усложняющиеся выражения.
Добро пожаловать в StackOverflow. Пожалуйста, совершите экскурсию и посмотрите Как спросить . Конкретно: вы разместили довольно много кода. Размещение минимально воспроизводимого примера поможет нам помочь вам.