Интерпретатор числовых выражений :)

Elina74

Помогите разобраться почему это он так странно работает...
Винды выдают сообщение, что программа выполнила некорректную операцию и будет закрыта.

resident-evil

А дебажить не пробовал?

Elina74

Пробовал. Ошибка происходит в самом конце перед завершением работы программы.
Есть версия, что это из-за утечки памяти... Кто может прокомментировать?

psm-home

<немного offtopic>
А в чём маза писания такой хрени самому? Есть же масса мест, где это можно стырить. Хотябы Страуструп. Или вообще взять что-то типа lex+yacc (flex+bison с ними обычно идут всякие калькуляторы в качестве примеров.

psm-home

Компилятор же зря ругаться не будет. Тебе же пишуть warning
E:\_Works_\delme\delme.cpp(30) : warning C4700: local variable 'endptr' used without having been initialized

Это и есть причина. Под отладчиком всё это видно.

float number{
char* s;
char** endptr;
int len = 0;
float result = 0;
s = new char[strlen(p)+1];
while( isdigit(*p) || *p=='e' || *p =='E' || *p=='-' || *p=='+' || *p =='.' ){
s[len] = *p;
p++;
len++;
}
s[len] = '\0';
result = strtod(s, endptr);// тут задница, т.к endptr ==NULL
while(**endptr!='\0'){
len--;
s[len]='\0';
p--;
result = strtod(s, endptr);
}
delete [] s;
return(result);
}

kokoc88

Два куска в твоём коде


...
p++;
...
delete [] p;

psm-home

Так должно быть лучше (но есть ещё глюк с памятью).
float number{
char* s;
char* endptr;
int len = 0;
float result = 0;
s = new char[strlen(p)+1];
while( isdigit(*p) || *p=='e' || *p =='E' || *p=='-' || *p=='+' || *p =='.' ){
s[len] = *p;
p++;
len++;
}
s[len] = '\0';
result = strtod(s, &endptr);
while(*endptr!='\0'){
len--;
s[len]='\0';
p--;
result = strtod(s, &endptr);
}
delete [] s;
return(result);
}

psm-home

Вот-вот, когда он избавится от AV, он налетит на _ASSERTE в delete[].

kokoc88

Прочитал про strtod. На самом деле он должен был написать :


char *endptr;
....
result = strtod(s, &endptr);

psm-home

На самом деле он должен был написать

А я за что её хватал!(с) То есть я же об этом уже написал выше.
Вот так оно даже не падает и считает.


// delme.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *p = NULL;
char *p0 = NULL;
float number;
float factor;
float term;
float expression;
float number{
char* s;
char* endptr;
int len = 0;
float result = 0;
s = new char[strlen(p)+1];
while( isdigit(*p) || *p=='e' || *p =='E' || *p=='-' || *p=='+' || *p =='.' ){
s[len] = *p;
p++;
len++;
}
s[len] = '\0';
result = strtod(s, &endptr);
while(*endptr!='\0'){
len--;
s[len]='\0';
p--;
result = strtod(s, &endptr);
}
delete [] s;
return(result);
}
float factor{
float result;
if(*p=='('){
p++;
result = expression;
p++;
}
else{
result = number;
}
return(result);
}
float term{
float result = factor;
if(*p=='*' || *p=='/'){
if(*p=='*'){
p++;
result *= factor;
}
else{
p++;
result /= factor;
}
}
return(result);
}
float expression{
float result;
if(*p=='-'){
p++;
result = -term;
}
else{
if(*p=='+'){
p++;
result = term;
}
else{
result = term;
}
}
if(*p=='+' || *p=='-'){
if(*p=='+'){
p++;
result += term;
}
else{
p++;
result -= term;
}
}
return(result);
}
void init{
long len = 0;
FILE* InFile = fopen("1.bas", "rt");
fseek(InFile, 0, SEEK_END);
len = ftell(InFile);
fseek(InFile, 0, SEEK_SET);
p = p0 = new char[len+1];
fread(p, 1, len, InFile);
p[len]='\0';
fclose(InFile);
}
void main{
init;
printf("\n%f\n", expression;
delete [] p0;
}

Elina74

Кажись теперь, когда исправил на
char* endptr
и разобрался с
delete [] p
уже работает.
Оставить комментарий
Имя или ник:
Комментарий: