gpt4 book ai didi

c - 在命令行读取表达式

转载 作者:行者123 更新时间:2023-11-30 19:25:33 24 4
gpt4 key购买 nike

我正在尝试编写一个计算器,它能够读取 (5+12*5)^2 等表达式;它不是波兰计算器。

目前我专注于如何读取数字并将它们存储在链接列表中。程序应该读取一行计算结果并等待下一个输入(就像在 shell 中接受命令一样)。

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>

#define MAX 100

struct n{
double value;
char op;
struct n *next;
};

void print_list(struct n *head);
void add_item(struct n **ptr, double *data);
void free_all(struct n *head);
void f(double x);

int main()
{
struct n *head = NULL;

char *buf = malloc(MAX * sizeof (*buf));
int n;
double num;

for(;;) {

if(fgets(buf, MAX, stdin) == NULL)
return 0;

while (*buf != '\n') {

if (isdigit(*buf)) {
sscanf(buf, "%lf%n", &num, &n);
add_item(&head, &num);
buf += n;
}

if (!isdigit(*buf)){
buf++;
}

print_list(head);
}
free(head);
}



return 0;
}

void print_list(struct n *head) {

if (head != NULL) {
f(head->value);
print_list(head->next);
}
}

void add_item(struct n **ptr, double *data)
{
struct n *item = malloc(sizeof *item);

item->value = *data;
item->next = *ptr;
item->op = '*';
*ptr = item;
}

void free_all(struct n *head)
{
struct n *tmp;

while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}

void f(double x)
{
double i, r = modf(x, &i);

if(fabs(r)<.00001)
printf("%.f ",i);

else printf("%f ",x);
}

我正在使用 fgets,并且能够读取输入,但程序进入无限循环。我不确定为此目的读取数据的最佳函数是什么。

最佳答案

简单的错误

if (isdigit(*buf)) {
sscanf(buf, "%lf%n", &num, &n);
add_item(&head, &num);
buf += n; // Here we are incrementing buf
}

if (!isdigit(*buf)){ // So here we are looking at index buf+n
buf++;
}

这里您需要做的是几个if else。但这里的另一件事是,首先检查它是否是数字,然后检查它是否不是,这是相当多余的。重写为:

if (isdigit(*buf)) {
sscanf(buf, "%lf%n", &num, &n);
add_item(&head, &num);
buf += n;
} else {
buf++;
}

但是,正如评论中已经提到的,在构造解析器时,链表并不是一个很好的策略。你应该使用一棵树来代替。您还应该阅读语法来定义语法。在这里阅读语法:https://en.wikipedia.org/wiki/Regular_grammar

关于c - 在命令行读取表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58623710/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com