C 通过函数传递字符串会剪切前几个字符
我必须制作一个代码,它接受中缀符号的表达式,并输出正确的答案 示例输入如下所示:C 通过函数传递字符串会剪切前几个字符,c,stdin,C,Stdin,我必须制作一个代码,它接受中缀符号的表达式,并输出正确的答案 示例输入如下所示: 3 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121 1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631 3.8120 / 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795 第一个输入
3
2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
3.8120 / 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
第一个输入是一个整数,表示后面将有多少个表达式
为了解决这个问题,我创建了一个函数result(),它接受一个包含表达式的字符串。此函数可用于循环的第一次迭代
从这个错误中,我怀疑我获取输入的方式有问题,因此我在主函数中放置了一个print语句,以查看是否从STDIN获得了正确的输入:
int main(void) {
int num; //get num of expressions
scanf("%d", &num);
getchar(); //get newline
char exp[MAX];
//gets the whole string of input
for(int a = 0; a < num; a++) {
fgets(exp, MAX, stdin);
exp[strlen(exp)-1] = 0;
printf("STDIN: %s\n", exp);
//double ans = result(exp);
memset(exp, 0, MAX);
//printf("%0.4lf\n\n", ans);
}
}
因此,从这里,我知道STDIN确实得到了正确的输入。接下来,在result函数中,我放置了一个print语句,用于检查输入到函数中的字符串的值。现在,如果我取消注释main中调用函数result的行,并输入相同的输入,我将得到不同的输出
STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
FUNCTION: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
STDIN: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
FUNCTION: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
STDIN: 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
FUNCTION: 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
为什么会发生这种情况?即使删除函数中的print语句,也会发生此错误。只要调用函数result()就会发生这种情况
调用函数时从STDIN输入:
STDIN: 2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
STDIN: 947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
STDIN: 5.3817 * 5.0096 * 1.0598 / 3.7128 + 5.8597 / 4.3995 ^ 5.1891 - 3.0547 / 2.5795
我怀疑这与空白有关,但我不知道在哪里会发生这种错误?我已经注意到新线了
完整代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#define MAX 100000
struct Stack {
int data[MAX];
int top;
};
typedef struct Stack Stack;
double numbers[MAX]; //stack for numbers
int numTop;
void Initialize(Stack *S) {
S->top = -1;
memset(S->data, 0, MAX);
}
void initNumbers() {
numTop = -1;
memset(numbers, 0, MAX);
}
char peek(Stack *S) {
return S->data[S->top];
}
void push(Stack *S, char c) {
S->top++;
S->data[S->top] = c;
}
char pop(Stack *S) {
char value = S->data[S->top];
S->top--;
return value;
}
int isEmpty(Stack *S) {
if(S->top == -1) {
return 1; //empty
} else {
return 0;
}
}
int isDigit(char c) {
if(c >= '0' && c <= '9' || c == '.') {
return 1;
} else {
return 0;
}
}
int isOperation(char c) {
if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^') {
return 1;
} else {
return 0;
}
}
double ConvertTodouble(char exp[], int a, int size) {
char temp[MAX];
memset(temp, 0, MAX);
for(int i = 0; i < size; i++) {
temp[i] = exp[a];
a++;
}
return atof(temp);
}
void pushNum(double num) { //for num array
numTop++;
numbers[numTop] = num;
}
double popNum() {
double result = numbers[numTop];
numTop--;
return result;
}
double evaluate(double a, double b, char op) {
if(op == '+') {
return a + b;
} else if(op == '-') {
return a - b;
} else if(op == '*') {
return a * b;
} else if(op == '/') {
return a / b;
} else if(op == '^') {
return pow(a, b);
}
}
int weight(char c) {
switch(c) {
case '+':
case '-': return 1;
break;
case '*':
case '/': return 2;
break;
case '^': return 3;
break;
}
}
//if isp > icp, pop (returns 1)
//this returns 1 if isp > icp (left associative)
//returns 1, we pop
int higherPrecedence(char instack, char incoming) {
int isp = weight(instack);
int icp = weight(incoming);
if((isp == icp) && instack == '^') {
return 0;
} else if((isp == icp) && instack != '^') {
return 1;
}
if(isp > icp) {
return 1;
} else {
return 0;
}
}
double result(char exp[]) {
Stack S; //stack for operations (+,-,*,/,^)
double ans = 0;
Initialize(&S);
initNumbers();
int len = strlen(exp);
int flag = 0;
for(int i = 0; i < len; i++) {
if(exp[i] == ' ') {
getchar();
} else if(isDigit(exp[i])) {
//gets number from char array and converts to double
flag = i; //flag determines how many spaces to move pointer later
for(int a = i; a < len; a++) {
if(exp[a] == ' ') {
break;
} else {
flag++;
}
}
int size = flag - i;
double number = ConvertTodouble(exp, i, size);
pushNum(number);
i = flag - 1; //update the index so we won't repeat operation
} else if (exp[i] == '(') {
push(&S, '(');
} else if(isOperation(exp[i])) {
while(!isEmpty(&S) && peek(&S) != '(' && higherPrecedence(peek(&S), exp[i])) {
char op = pop(&S);
double b = popNum();
double a = popNum();
ans = evaluate(a,b,op);
pushNum(ans);
}
push(&S, exp[i]);
} else if(exp[i] == ')') {
while(!isEmpty(&S) && peek(&S) != '(') {
char op = pop(&S);
double b = popNum();
double a = popNum();
ans = evaluate(a,b,op);
pushNum(ans);
}
char throw = pop(&S); //this gets the '('
}
}
while(!isEmpty(&S)) {
char op = pop(&S);
double b = popNum();
double a = popNum();
ans = evaluate(a,b,op);
pushNum(ans);
if(numTop == 0) {
break;
}
}
return ans;
}
int main(void) {
int num; //get num of expressions
scanf("%d", &num);
getchar(); //get newline
char exp[MAX];
//gets the whole string of input
for(int a = 0; a < num; a++) {
printf("Before: %s\n", exp);
fgets(exp, MAX, stdin);
exp[strlen(exp)-1] = 0;
printf("STDIN: %s\n", exp);
double ans = result(exp);
memset(exp, 0, MAX);
//printf("%0.4lf\n\n", ans);
}
}
#包括
#包括
#包括
#包括
#包括
#定义最大100000
结构堆栈{
整数数据[MAX];
int top;
};
typedef结构堆栈;
双倍数字[最大值]//堆叠数字
int numTop;
无效初始化(堆栈*S){
S->top=-1;
memset(S->data,0,MAX);
}
void initNumbers(){
numTop=-1;
memset(数字,0,最大值);
}
字符窥视(堆栈*S){
返回S->数据[S->顶部];
}
无效推送(堆栈*S,字符c){
S->top++;
S->数据[S->顶部]=c;
}
字符pop(堆栈*S){
char value=S->data[S->top];
S->顶部--;
返回值;
}
int isEmpty(堆栈*S){
如果(S->top==-1){
返回1;//空
}否则{
返回0;
}
}
int isDigit(字符c){
如果(c>='0'&&c icp,pop(返回1)
//如果isp>icp(左关联),则返回1
//返回1,我们弹出
int HigherRecessence(字符安装,字符输入){
int isp=重量(instack);
int icp=重量(输入);
如果((isp==icp)和&instack=='^'){
返回0;
}如果((isp==icp)和&instack!='^'){
返回1;
}
如果(isp>icp){
返回1;
}否则{
返回0;
}
}
双重结果(char exp[]){
堆栈S;//操作的堆栈(+、-、*、/、^)
双ans=0;
初始化(&S);
initNumbers();
int len=strlen(exp);
int标志=0;
对于(int i=0;i
我想我找到了漏洞
你可以看到这里发生了什么
1.8752 ^ 3.7947 ^ 3.9259 / 5.0828 ^ 2.3765 ^ 1.6631
^
|
you got it from here.
12名查卡特失踪
检查前一行
2.8982 + 4.8674 - 5.5170 - 1.4080 + 3.6204 - 3.8340 - 5.9121
x x x x x x x x x x x x
有12个空间
这就是导致错误的原因
for(int i = 0; i < len; i++) {
if(exp[i] == ' ') {
getchar();
for(int i=0;i
更改代码的逻辑。希望这能有所帮助。嗯……这三个字符对我来说都一样?我是否遗漏了什么?请注意,第二个的正确输入应该是1.8752^3.7947,等等。但是,当我调用函数时,第二个会剪切前几个字符,并从947^3.9259开始。您能发布完整的代码吗?我无法验证您所说的内容哦,这个。好吧!再次查看原始帖子!@Katrina:希望你能得到解释。
for(int i = 0; i < len; i++) {
if(exp[i] == ' ') {
getchar();