I was working on the Calculator problem provided in Bjarne Stroustrup's book - Programming Principles and Practice Using C++. An exercise stated to modify a class to use an istream as an explicit parameter, to allow input from a file. The code works if I pass cin
to the function. Howerver, if I give it an ifstream
, the program does what it's supposed to do, then exits with a segmentation fault. Here's the main()
function:
#include "std_lib_facilities.h"
#include "token.h"
#include "variable.h"
#include "calculator.h"
//NOTE: The Token_stream works with files, but not fully:
//it reads from them, does the correct calculations, but then crashes with a a core dump error, double free or corruption (out)
ifstream istr;
Token_stream ts(istr);
Symbol_table st;
void initialize_custom_variables();
int main()
{
istr.open("input.txt");
initialize_custom_variables();
intro_message();
calculate(ts, st);
istr.close();
return 0;
}
void initialize_custom_variables()
{
st.define_variable("pi", 3.14159, true);
st.define_variable("e",2.71828 , true);
}
Here are the header files used:
token.h
#pragma once
#include "std_lib_facilities.h"
//Token implementation----------------------------------------------------------
class Token {
public:
char type;
double value;
string name; // used for a Token of type name
Token(char ch) :type{ ch }, value{ 0 } {};
Token(char ch, double val) :type{ ch }, value{ val } {};
Token(char ch, string n) :type{ ch }, name{ n } {};
};
//-------------------------------------------------------------------------------
//Token_stream implementation----------------------------------------------------
class Token_stream {
public:
Token_stream(istream& istr);
Token get();
void putback(Token t);
void ignore(char c);
private:
bool isFull;
Token buffer;
istream& istr_p;
};
variable.h
#pragma once
#include "std_lib_facilities.h"
//Variable implementation--------------------------------------------------------
class Variable
{
public:
std::string name;
double value;
bool isConst;
Variable(std::string st, double v, bool b) : name{ st }, value{ v }, isConst{ b } {}
Variable(std::string st, double v) : name{ st }, value{ v }, isConst{ false } {}
};
class Symbol_table
{
public:
double get_value(std::string s);
void set_value(std::string s, double n); //We all have our daemons, running in the background without us realising it.
bool is_declared(std::string var);
double define_variable(std::string var, double val, bool isConst);
void show_variables();
private:
vector <Variable> var_table;
};
calculator.h
#pragma once
// forward declarations
//class Token_stream;
//class Symbol_table;
#include "token.h"
//Declarations and Initializations-----------------------------------------------
void calculate(Token_stream& ts, Symbol_table& st);
double statement(Token_stream& ts, Symbol_table& st);
double declaration(Token_stream& ts, Symbol_table& st);
double square_root(Token_stream& ts, Symbol_table& st);
double powerf(Token_stream& ts, Symbol_table& st);
double expression(Token_stream& ts, Symbol_table& st);
double term(Token_stream& ts, Symbol_table& st);
double factorial(Token_stream& ts, Symbol_table& st);
double primary(Token_stream& ts, Symbol_table& st);
double variable(Token_stream& ts, Symbol_table& st);
void intro_message();
void cleanup(Token_stream&);
//-------------------------------------------------------------------------------
Aucun commentaire:
Enregistrer un commentaire