std::out of range in a noxim code - c++
Im starting with some SystemC coding and i'm trying to use a Network-on-chip simulator called "Noxim", which i've heard is very smooth and simple. However, im getting this common error when I'm trying to "make" some part of the simulation
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr
Abort
I think it comes from a cpp code, which I DO NOT own and, sincerely, dont fully understand. The code can be found bellow, and the full Noxim distribution can be found here: https://github.com/alexayin/Noxim
The code is at Noxim/other/
Noxim_explorer.cpp and sim.cfg are strongly related to the lab im trying to do.
Please, if someone has solved this problem or have any idea, it would be very helpful.
FOR THE RECORD: I got stucked when trying to follow this lab http://access.ee.ntu.edu.tw/noxim/Lab2.pdf, 'cause I couldnt get any info in the matlab file
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <string>
#include <cassert>
#include <cstdlib>
#include <sys/time.h>
using namespace std;
//---------------------------------------------------------------------------
#define DEFAULT_KEY "default"
#define AGGREGATION_KEY "aggregation"
#define EXPLORER_KEY "explorer"
#define SIMULATOR_LABEL "simulator"
#define REPETITIONS_LABEL "repetitions"
#define TMP_DIR_LABEL "tmp"
#define DEF_SIMULATOR "./noxim"
#define DEF_REPETITIONS 5
#define DEF_TMP_DIR "./"
#define TMP_FILE_NAME ".noxim_explorer.tmp"
#define RPACKETS_LABEL "% Total received packets:"
#define RFLITS_LABEL "% Total received flits:"
#define AVG_DELAY_LABEL "% Global average delay (cycles):"
#define AVG_THROUGHPUT_LABEL "% Global average throughput (flits/cycle):"
#define THROUGHPUT_LABEL "% Throughput (flits/cycle/IP):"
#define MAX_DELAY_LABEL "% Max delay (cycles):"
#define TOTAL_ENERGY_LABEL "% Total energy (J):"
#define MATLAB_VAR_NAME "data"
#define MATRIX_COLUMN_WIDTH 15
//---------------------------------------------------------------------------
typedef unsigned int uint;
// parameter values
typedef vector<string> TParameterSpace;
// parameter name, parameter space
typedef map<string, TParameterSpace> TParametersSpace;
// parameter name, parameter value
typedef vector<pair<string, string> > TConfiguration;
typedef vector<TConfiguration> TConfigurationSpace;
struct TExplorerParams
{
string simulator;
string tmp_dir;
int repetitions;
};
struct TSimulationResults
{
double avg_delay;
double throughput;
double avg_throughput;
double max_delay;
double total_energy;
unsigned int rpackets;
unsigned int rflits;
};
//---------------------------------------------------------------------------
double GetCurrentTime()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + (tv.tv_usec * 1.0e-6);
}
//---------------------------------------------------------------------------
void TimeToFinish(double elapsed_sec,
int completed, int total,
int& hours, int& minutes, int &seconds)
{
double total_time_sec = (elapsed_sec * total)/completed;
double remain_time_sec = total_time_sec - elapsed_sec;
seconds = (int)remain_time_sec % 60;
minutes = ((int)remain_time_sec / 60) % 60;
hours = (int)remain_time_sec / 3600;
}
//---------------------------------------------------------------------------
bool IsComment(const string& s)
{
return (s == "" || s.at(0) == '%');
}
//---------------------------------------------------------------------------
string TrimLeftAndRight(const string& s)
{
int len = s.length();
int i, j;
for (i=0; i<len && s.at(i) == ' '; i++) ;
for (j=len-1; j>=0 && s.at(j) == ' '; j--) ;
return s.substr(i,j-i+1);
}
//---------------------------------------------------------------------------
bool ExtractParameter(const string& s, string& parameter)
{
uint i = s.find("[");
if (i != string::npos)
{
uint j = s.rfind("]");
if (j != string::npos)
{
parameter = s.substr(i+1, j-i-1);
return true;
}
}
return false;
}
//---------------------------------------------------------------------------
bool GetNextParameter(ifstream& fin, string& parameter)
{
bool found = false;
while (!fin.eof() && !found)
{
string s;
getline(fin, s);
if (!IsComment(s))
found = ExtractParameter(s, parameter);
}
return found;
}
//---------------------------------------------------------------------------w
string MakeStopParameterTag(const string& parameter)
{
string sparameter = "[/" + parameter + "]";
return sparameter;
}
//---------------------------------------------------------------------------
bool ManagePlainParameterSet(ifstream& fin,
const string& parameter,
TParametersSpace& params_space,
string& error_msg)
{
string str_stop = MakeStopParameterTag(parameter);
bool stop = false;
while (!fin.eof() && !stop)
{
string s;
getline(fin, s);
if (!IsComment(s))
{
if (s.find(str_stop) != string::npos)
stop = true;
else
params_space[parameter].push_back(TrimLeftAndRight(s));
}
}
return true;
}
//---------------------------------------------------------------------------
bool ExpandInterval(const string& sint,
TParameterSpace& ps,
string& error_msg)
{
istringstream iss(sint);
double min, max, step;
iss >> min;
iss >> max;
iss >> step;
string param_suffix;
getline(iss, param_suffix);
for (double v=min; v<=max; v+=step)
{
ostringstream oss;
oss << v;
ps.push_back(oss.str() + param_suffix);
}
return true;
}
//---------------------------------------------------------------------------
bool ManageCompressedParameterSet(ifstream& fin,
const string& parameter,
TParametersSpace& params_space,
string& error_msg)
{
string str_stop = MakeStopParameterTag(parameter);
bool stop = false;
while (!fin.eof() && !stop)
{
string s;
getline(fin, s);
if (!IsComment(s))
{
if (s.find(str_stop) != string::npos)
stop = true;
else
{
if (!ExpandInterval(s, params_space[parameter], error_msg))
return false;
}
}
}
return true;
}
//---------------------------------------------------------------------------
bool ManageParameter(ifstream& fin,
const string& parameter,
TParametersSpace& params_space,
string& error_msg)
{
bool err;
if (parameter == "pir")
err = ManageCompressedParameterSet(fin, parameter, params_space, error_msg);
else
err = ManagePlainParameterSet(fin, parameter, params_space, error_msg);
return err;
}
//---------------------------------------------------------------------------
bool ParseConfigurationFile(const string& fname,
TParametersSpace& params_space,
string& error_msg)
{
ifstream fin(fname.c_str(), ios::in);
if (!fin)
{
error_msg = "Cannot open " + fname;
return false;
}
while (!fin.eof())
{
string parameter;
if ( GetNextParameter(fin, parameter) )
{
if (!ManageParameter(fin, parameter, params_space, error_msg))
return false;
}
}
return true;
}
//---------------------------------------------------------------------------
bool LastCombination(const vector<pair<int,int> >& indexes)
{
for (uint i=0; i<indexes.size(); i++)
if (indexes[i].first < indexes[i].second-1)
return false;
return true;
}
//---------------------------------------------------------------------------
bool IncrementCombinatorialIndexes(vector<pair<int,int> >& indexes)
{
for (uint i=0; i<indexes.size(); i++)
{
if (indexes[i].first < indexes[i].second - 1)
{
indexes[i].first++;
return true;
}
indexes[i].first = 0;
}
return false;
}
//---------------------------------------------------------------------------
TConfigurationSpace Explore(const TParametersSpace& params_space)
{
TConfigurationSpace conf_space;
vector<pair<int,int> > indexes; // <index, max_index>
for (TParametersSpace::const_iterator psi=params_space.begin();
psi!=params_space.end(); psi++)
indexes.push_back(pair<int,int>(0, psi->second.size()));
do
{
int i = 0;
TConfiguration conf;
for (TParametersSpace::const_iterator psi=params_space.begin();
psi!=params_space.end(); psi++)
{
conf.push_back( pair<string,string>(psi->first,
psi->second[indexes[i].first]));
i++;
}
conf_space.push_back(conf);
}
while (IncrementCombinatorialIndexes(indexes));
return conf_space;
}
//---------------------------------------------------------------------------
bool RemoveParameter(TParametersSpace& params_space,
const string& param_name,
TParameterSpace& param_space,
string& error_msg)
{
TParametersSpace::iterator i = params_space.find(param_name);
if (i == params_space.end())
{
error_msg = "Cannot extract parameter '" + param_name + "'";
return false;
}
param_space = params_space[param_name];
params_space.erase(i);
return true;
}
//---------------------------------------------------------------------------
bool RemoveAggregateParameters(TParametersSpace& params_space,
TParameterSpace& aggregated_params,
TParametersSpace& aggragated_params_space,
string& error_msg)
{
for (uint i=0; i<aggregated_params.size(); i++)
{
string param_name = aggregated_params[i];
TParameterSpace param_space;
if (!RemoveParameter(params_space, param_name, param_space, error_msg))
return false;
aggragated_params_space[param_name] = param_space;
}
return true;
}
//---------------------------------------------------------------------------
string ParamValue2Cmd(const pair<string,string>& pv)
{
string cmd;
if (pv.first == "topology")
{
istringstream iss(pv.second);
int width, height;
char times;
iss >> width >> times >> height;
ostringstream oss;
oss << "-dimx " << width << " -dimy " << height;
cmd = oss.str();
}
else
cmd = "-" + pv.first + " " + pv.second;
return cmd;
}
//---------------------------------------------------------------------------
string Configuration2CmdLine(const TConfiguration& conf)
{
string cl;
for (uint i=0; i<conf.size(); i++)
cl = cl + ParamValue2Cmd(conf[i]) + " ";
return cl;
}
//---------------------------------------------------------------------------
string Configuration2FunctionName(const TConfiguration& conf)
{
string fn;
for (uint i=0; i<conf.size(); i++)
fn = fn + conf[i].first + "_" + conf[i].second + "__";
// Replace " ", "-", ".", "/" with "_"
int len = fn.length();
for (int i=0; i<len; i++)
if (fn.at(i) == ' ' || fn.at(i) == '.' || fn.at(i) == '-' || fn.at(i) == '/')
fn[i] = '_';
return fn;
}
//---------------------------------------------------------------------------
bool ExtractExplorerParams(const TParameterSpace& explorer_params,
TExplorerParams& eparams,
string& error_msg)
{
eparams.simulator = DEF_SIMULATOR;
eparams.tmp_dir = DEF_TMP_DIR;
eparams.repetitions = DEF_REPETITIONS;
for (uint i=0; i<explorer_params.size(); i++)
{
istringstream iss(explorer_params[i]);
string label;
iss >> label;
if (label == SIMULATOR_LABEL)
iss >> eparams.simulator;
else if (label == REPETITIONS_LABEL)
iss >> eparams.repetitions;
else if (label == TMP_DIR_LABEL)
iss >> eparams.tmp_dir;
else
{
error_msg = "Invalid explorer option '" + label + "'";
return false;
}
}
return true;
}
//---------------------------------------------------------------------------
bool PrintHeader(const string& fname,
const TExplorerParams& eparams,
const string& def_cmd_line, const string& conf_cmd_line,
ofstream& fout,
string& error_msg)
{
fout.open(fname.c_str(), ios::out);
if (!fout)
{
error_msg = "Cannot create " + fname;
return false;
}
fout << "% fname: " << fname << endl
<< "% " << eparams.simulator << " "
<< conf_cmd_line << " " << def_cmd_line
<< endl << endl;
return true;
}
//---------------------------------------------------------------------------
bool PrintMatlabFunction(const string& mfname,
ofstream& fout,
string& error_msg)
{
fout << "function [max_pir, max_throughput, min_delay] = " << mfname << "(symbol)" << endl
<< endl;
return true;
}
//---------------------------------------------------------------------------
bool ReadResults(const string& fname,
TSimulationResults& sres,
string& error_msg)
{
ifstream fin(fname.c_str(), ios::in);
if (!fin)
{
error_msg = "Cannot read " + fname;
return false;
}
int nread = 0;
while (!fin.eof())
{
string line;
getline(fin, line);
uint pos;
pos = line.find(RPACKETS_LABEL);
if (pos != string::npos)
{
nread++;
istringstream iss(line.substr(pos + string(RPACKETS_LABEL).size()));
iss >> sres.rpackets;
continue;
}
pos = line.find(RFLITS_LABEL);
if (pos != string::npos)
{
nread++;
istringstream iss(line.substr(pos + string(RFLITS_LABEL).size()));
iss >> sres.rflits;
continue;
}
pos = line.find(AVG_DELAY_LABEL);
if (pos != string::npos)
{
nread++;
istringstream iss(line.substr(pos + string(AVG_DELAY_LABEL).size()));
iss >> sres.avg_delay;
continue;
}
pos = line.find(AVG_THROUGHPUT_LABEL);
if (pos != string::npos)
{
nread++;
istringstream iss(line.substr(pos + string(AVG_THROUGHPUT_LABEL).size()));
iss >> sres.avg_throughput;
continue;
}
pos = line.find(THROUGHPUT_LABEL);
if (pos != string::npos)
{
nread++;
istringstream iss(line.substr(pos + string(THROUGHPUT_LABEL).size()));
iss >> sres.throughput;
continue;
}
pos = line.find(MAX_DELAY_LABEL);
if (pos != string::npos)
{
nread++;
istringstream iss(line.substr(pos + string(MAX_DELAY_LABEL).size()));
iss >> sres.max_delay;
continue;
}
pos = line.find(TOTAL_ENERGY_LABEL);
if (pos != string::npos)
{
nread++;
istringstream iss(line.substr(pos + string(TOTAL_ENERGY_LABEL).size()));
iss >> sres.total_energy;
continue;
}
}
if (nread != 7)
{
error_msg = "Output file " + fname + " corrupted";
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool RunSimulation(const string& cmd_base,
const string& tmp_dir,
TSimulationResults& sres,
string& error_msg)
{
string tmp_fname = tmp_dir + TMP_FILE_NAME;
// string cmd = cmd_base + " >& " + tmp_fname; // this works only with csh and bash
string cmd = cmd_base + " >" + tmp_fname + " 2>&1"; // this works with sh, csh, and bash!
cout << cmd << endl;
system(cmd.c_str());
if (!ReadResults(tmp_fname, sres, error_msg))
return false;
string rm_cmd = string("rm -f ") + tmp_fname;
system(rm_cmd.c_str());
return true;
}
//---------------------------------------------------------------------------
string ExtractFirstField(const string& s)
{
istringstream iss(s);
string sfirst;
iss >> sfirst;
return sfirst;
}
//---------------------------------------------------------------------------
bool RunSimulations(double start_time,
pair<uint,uint>& sim_counter,
const string& cmd, const string& tmp_dir, const int repetitions,
const TConfiguration& aggr_conf,
ofstream& fout,
string& error_msg)
{
int h, m, s;
for (int i=0; i<repetitions; i++)
{
cout << "# simulation " << (++sim_counter.first) << " of " << sim_counter.second;
if (i != 0)
cout << ", estimated time to finish " << h << "h " << m << "m " << s << "s";
cout << endl;
TSimulationResults sres;
if (!RunSimulation(cmd, tmp_dir, sres, error_msg))
return false;
double current_time = GetCurrentTime();
TimeToFinish(current_time-start_time, sim_counter.first, sim_counter.second, h, m, s);
// Print aggragated parameters
fout << " ";
for (uint i=0; i<aggr_conf.size(); i++)
fout << setw(MATRIX_COLUMN_WIDTH) << ExtractFirstField(aggr_conf[i].second); // this fix the problem with pir
// fout << setw(MATRIX_COLUMN_WIDTH) << aggr_conf[i].second;
// Print results;
fout << setw(MATRIX_COLUMN_WIDTH) << sres.avg_delay
<< setw(MATRIX_COLUMN_WIDTH) << sres.throughput
<< setw(MATRIX_COLUMN_WIDTH) << sres.max_delay
<< setw(MATRIX_COLUMN_WIDTH) << sres.total_energy
<< setw(MATRIX_COLUMN_WIDTH) << sres.rpackets
<< setw(MATRIX_COLUMN_WIDTH) << sres.rflits
<< endl;
}
return true;
}
//---------------------------------------------------------------------------
bool PrintMatlabVariableBegin(const TParametersSpace& aggragated_params_space,
ofstream& fout, string& error_msg)
{
fout << MATLAB_VAR_NAME << " = [" << endl;
fout << "% ";
for (TParametersSpace::const_iterator i=aggragated_params_space.begin();
i!=aggragated_params_space.end(); i++)
fout << setw(MATRIX_COLUMN_WIDTH) << i->first;
fout << setw(MATRIX_COLUMN_WIDTH) << "avg_delay"
<< setw(MATRIX_COLUMN_WIDTH) << "throughput"
<< setw(MATRIX_COLUMN_WIDTH) << "max_delay"
<< setw(MATRIX_COLUMN_WIDTH) << "total_energy"
<< setw(MATRIX_COLUMN_WIDTH) << "rpackets"
<< setw(MATRIX_COLUMN_WIDTH) << "rflits";
fout << endl;
return true;
}
//---------------------------------------------------------------------------
bool GenMatlabCode(const string& var_name,
const int fig_no,
const int repetitions, const int column,
ofstream& fout, string& error_msg)
{
fout << var_name << " = [];" << endl
<< "for i = 1:rows/" << repetitions << "," << endl
<< " ifirst = (i - 1) * " << repetitions << " + 1;" << endl
<< " ilast = ifirst + " << repetitions << " - 1;" << endl
<< " tmp = " << MATLAB_VAR_NAME << "(ifirst:ilast, cols-6+" << column << ");" << endl
<< " avg = mean(tmp);" << endl
<< " [h sig ci] = ttest(tmp, 0.1);" << endl
<< " ci = (ci(2)-ci(1))/2;" << endl
<< " " << var_name << " = [" << var_name << "; " << MATLAB_VAR_NAME << "(ifirst, 1:cols-6), avg ci];" << endl
<< "end" << endl
<< endl;
fout << "figure(" << fig_no << ");" << endl
<< "hold on;" << endl
<< "plot(" << var_name << "(:,1), " << var_name << "(:,2), symbol);" << endl
<< endl;
return true;
}
//---------------------------------------------------------------------------
bool GenMatlabCodeSaturationAnalysis(const string& var_name,
ofstream& fout, string& error_msg)
{
fout << endl
<< "%-------- Saturation Analysis -----------" << endl
<< "slope=[];" << endl
<< "for i=2:size(" << var_name << "_throughput,1)," << endl
<< " slope(i-1) = (" << var_name << "_throughput(i,2)-" << var_name << "_throughput(i-1,2))/(" << var_name << "_throughput(i,1)-" << var_name << "_throughput(i-1,1));" << endl
<< "end" << endl
<< endl
<< "for i=2:size(slope,2)," << endl
<< " if slope(i) < (0.95*mean(slope(1:i)))" << endl
<< " max_pir = " << var_name << "_throughput(i, 1);" << endl
<< " max_throughput = " << var_name << "_throughput(i, 2);" << endl
<< " min_delay = " << var_name << "_delay(i, 2);" << endl
<< " break;" << endl
<< " end" << endl
<< "end" << endl;
return true;
}
//---------------------------------------------------------------------------
bool PrintMatlabVariableEnd(const int repetitions,
ofstream& fout, string& error_msg)
{
fout << "];" << endl << endl;
fout << "rows = size(" << MATLAB_VAR_NAME << ", 1);" << endl
<< "cols = size(" << MATLAB_VAR_NAME << ", 2);" << endl
<< endl;
if (!GenMatlabCode(string(MATLAB_VAR_NAME) + "_delay", 1,
repetitions, 1, fout, error_msg))
return false;
if (!GenMatlabCode(string(MATLAB_VAR_NAME) + "_throughput", 2,
repetitions, 2, fout, error_msg))
return false;
if (!GenMatlabCode(string(MATLAB_VAR_NAME) + "_maxdelay", 3,
repetitions, 3, fout, error_msg))
return false;
if (!GenMatlabCode(string(MATLAB_VAR_NAME) + "_totalenergy", 4,
repetitions, 4, fout, error_msg))
return false;
if (!GenMatlabCodeSaturationAnalysis(string(MATLAB_VAR_NAME), fout, error_msg))
return false;
return true;
}
//---------------------------------------------------------------------------
bool RunSimulations(const TConfigurationSpace& conf_space,
const TParameterSpace& default_params,
const TParametersSpace& aggragated_params_space,
const TParameterSpace& explorer_params,
string& error_msg)
{
TExplorerParams eparams;
if (!ExtractExplorerParams(explorer_params, eparams, error_msg))
return false;
// Make dafault parameters string
string def_cmd_line;
for (uint i=0; i<default_params.size(); i++)
def_cmd_line = def_cmd_line + default_params[i] + " ";
// Explore configuration space
TConfigurationSpace aggr_conf_space = Explore(aggragated_params_space);
pair<uint,uint> sim_counter(0, conf_space.size() * aggr_conf_space.size() * eparams.repetitions);
double start_time = GetCurrentTime();
for (uint i=0; i<conf_space.size(); i++)
{
string conf_cmd_line = Configuration2CmdLine(conf_space[i]);
string mfname = Configuration2FunctionName(conf_space[i]);
string fname = mfname + ".m";
ofstream fout;
if (!PrintHeader(fname, eparams,
def_cmd_line, conf_cmd_line, fout, error_msg))
return false;
if (!PrintMatlabFunction(mfname, fout, error_msg))
return false;
if (!PrintMatlabVariableBegin(aggragated_params_space, fout, error_msg))
return false;
for (uint j=0; j<aggr_conf_space.size(); j++)
{
string aggr_cmd_line = Configuration2CmdLine(aggr_conf_space[j]);
/*
string cmd = eparams.simulator + " "
+ def_cmd_line + " "
+ conf_cmd_line + " "
+ aggr_cmd_line;
*/
string cmd = eparams.simulator + " "
+ aggr_cmd_line + " "
+ def_cmd_line + " "
+ conf_cmd_line;
if (!RunSimulations(start_time,
sim_counter, cmd, eparams.tmp_dir, eparams.repetitions,
aggr_conf_space[j], fout, error_msg))
return false;
}
if (!PrintMatlabVariableEnd(eparams.repetitions, fout, error_msg))
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool RunSimulations(const string& script_fname,
string& error_msg)
{
TParametersSpace ps;
if (!ParseConfigurationFile(script_fname, ps, error_msg))
return false;
TParameterSpace default_params;
if (!RemoveParameter(ps, DEFAULT_KEY, default_params, error_msg))
cout << "Warning: " << error_msg << endl;
TParameterSpace aggregated_params;
TParametersSpace aggragated_params_space;
if (!RemoveParameter(ps, AGGREGATION_KEY, aggregated_params, error_msg))
cout << "Warning: " << error_msg << endl;
else
if (!RemoveAggregateParameters(ps, aggregated_params,
aggragated_params_space, error_msg))
return false;
TParameterSpace explorer_params;
if (!RemoveParameter(ps, EXPLORER_KEY, explorer_params, error_msg))
cout << "Warning: " << error_msg << endl;
TConfigurationSpace conf_space = Explore(ps);
if (!RunSimulations(conf_space, default_params,
aggragated_params_space, explorer_params, error_msg))
return false;
return true;
}
//---------------------------------------------------------------------------
int main(int argc, char **argv)
{
if (argc < 2)
{
cout << "Usage: " << argv[0] << " <cfg file> [<cfg file>]" << endl;
return -1;
}
for (int i=1; i<argc; i++)
{
string fname(argv[i]);
cout << "# Exploring configuration space " << fname << endl;
string error_msg;
if (!RunSimulations(fname, error_msg))
cout << "Error: " << error_msg << endl;
cout << endl;
}
return 0;
}
//---------------------------------------------------------------------------
U are probably using a 64 bit pc
At Noxim_explorer.cpp
change
///////////////////////////////
uint pos;
pos = line.find(RPACKETS_LABEL);
///////////////////////////////
to ...
///////////////////////////////
std::size_t pos = line.find(RPACKETS_LABEL);
///////////////////////////////
It should work .. and generate the matlab file
Related
How can I search for a match through a vector of objects? [closed]
Closed. This question needs to be more focused. It is not currently accepting answers. Want to improve this question? Update the question so it focuses on one problem only by editing this post. Closed 4 years ago. Improve this question I am building up a program where I create a vector of objects, the input variables that create the object are read from a .txt file. I want to check if the "ID" of the object introduced by the user exists in order to continue. vector<Producto> vectorProductos; while(file >> sID >> sDesc >> sUMed >> sFam >> sClass >> dVolumen >> dLongitud >> sPrecio){ vectorProductos.push_back(Producto(sID, sDesc, sUMed,sFam, sClass, dVolumen, dLongitud, stringToDouble(sPrecio))); iNumProductos++; } file.close(); int iNumPartidas; cout << "iNumPartidas? " << endl; cin >> iNumPartidas; for(unsigned int iP = 1; iP <= iNumPartidas; iP++){ cout << endl << "Partida " << iP << ":" << endl; cout << "Clave de partida:\t"; cin >> sPartida; for(unsigned int iPrd = 0; iPrd < iNumProductos; iPrd++){ cout << endl << "Clave de producto " << iPrd+1 << ":\t"; cin >> sClave; if(sClave == vectorProductos[iPrd].getClave()){ cout << endl << "Cantidad:\t"; cin >> iCantProdxP; }else{ cout << "Producto no existe" << endl; } } } Producto class #ifndef Producto_h #define Producto_h #include <stdio.h> #include <string> #include <iostream> using namespace std; class Producto{ protected: string _sClave, _sDescripcion, _sUMed, _sClass, _sFam; double _dVolumen, _dPrecio, _dLongitud; public: Producto(); Producto(string, string, string, string, string, double, double, double); inline string getClave(){return _sClave;} inline string getDescripcion(){return _sDescripcion;} inline string getUMed(){return _sUMed;} inline string getFam(){return _sFam;} inline string getClass(){return _sClass;} inline double getVol(){return _dVolumen;} inline double getPrecio(){return _dPrecio;} inline double getLongitud(){return _dLongitud;} inline void setClave(string sClave){_sClave = sClave;} inline void setDescripcion(string sDescripcion){_sDescripcion = sDescripcion;} inline void setUMed(string sUMed){_sUMed = sUMed;} inline void setFam(string sFam){_sFam = sFam;} inline void setClass(string sClass){_sClass = sClass;} inline void setVol(double dVolumen){_dVolumen = dVolumen;} inline void setPrecio(double dPrecio){_dPrecio = dPrecio;} inline void setLongitud(double dLongitud){_dLongitud = dLongitud;} void toString(); }; Producto::Producto(){ _sClave = ""; _sDescripcion = "Falta descripcion"; _sUMed = "N/A"; _sFam = "Sin Familia"; _sClass = "Sin clase"; _dVolumen = 0.0; _dPrecio = 0.0; _dLongitud = 0.0; } Producto::Producto(string sClave, string sDescripcion, string sUMed, string sFam, string sClass, double dVolumen, double dLongitud, double dPrecio){ _sClave = sClave; _sDescripcion = sDescripcion; _sUMed = sUMed; _sFam = sFam; _sClass = sClass; _dVolumen = dVolumen; _dPrecio = dPrecio; _dLongitud = dLongitud; } void Producto::toString(){ cout << "\nProducto: " << _sClave; cout << "\nDescripcion: " << _sDescripcion; cout << "\nUnidad de Medida: " << _sUMed; cout << "\nFamilia: " << _sFam; cout << "\nClase: " << _sClass; cout << "\nVolumen: " << _dVolumen; cout << "\nLongitud: " << _dLongitud; cout << "\nPrecio: " << _dPrecio; cout << endl; } What I need is to see if that "ID" that the user is going to input actually exists and if not mark error. When I run my program I have to type in the ID of the first product to match it with the index number of the loop, and that is the only way it works but I need the program to match it with any "Producto" regardless of the position or index.
In your inner loop, you are prompting the user for an ID on every loop iteration and then comparing that ID only to the product at the index of the current loop iteration. You need to prompt the user one time BEFORE entering the loop and then compare the ID to every product until you find a match: std::cout << endl << "Clave de producto:\t"; std::cin >> sClave; bool found = false; for (std::size_t iPrd = 0; iPrd < vectorProductos.size(); ++iPrd) { if (sClave == vectorProductos[iPrd].getClave()) { found = true; break; } } if (found) { // do something ... } else { std::cout << "Producto no existe" << std::endl; } Alternatively, you should use std::find_if() instead of searching manually, eg: Producto.h #ifndef Producto_h #define Producto_h #include <iostream> #include <string> class Producto { protected: std::string _sClave, _sDescripcion, _sUMed, _sClass, _sFam; double _dVolumen, _dPrecio, _dLongitud; public: Producto(); Producto(std::string, std::string, std::string, std::string, std::string, double, double, double); std::string getClave() const { return _sClave; } std::string getDescripcion() const { return _sDescripcion; } std::string getUMed() const { return _sUMed; } std::string getFam() const { return _sFam; } std::string getClass() const { return _sClass; } double getVol() const { return _dVolumen; } double getPrecio() const { return _dPrecio; } double getLongitud() const { return _dLongitud; } void setClave(std::string sClave) { _sClave = sClave; } void setDescripcion(std::string sDescripcion) { _sDescripcion = sDescripcion; } void setUMed(std::string sUMed) { _sUMed = sUMed; } void setFam(std::string sFam) { _sFam = sFam; } void setClass(std::string sClass) { _sClass = sClass; } void setVol(double dVolumen) { _dVolumen = dVolumen; } void setPrecio(double dPrecio) { _dPrecio = dPrecio; } void setLongitud(double dLongitud) { _dLongitud = dLongitud; } std::string toString() const; }; std::istream& operator>>(std::istream &in, Producto &p); #endif Producto.cpp #include "Producto.h" #include <sstream> std::istream& operator>>(std::istream &in, Producto &p) { std::string sID, sDesc, sUMed, sFam, sClass, sPrecio; double dVolumen, dLongitud; if (in >> sID >> sDesc >> sUMed >> sFam >> sClass >> dVolumen >> dLongitud >> sPrecio) { p.setClave(sID); p.setDescripcion(sDesc); p.setUMed(sUMed); p.setFam(sFam); p.setClass(sClass); p.setVol(dVolumen); p.setLongitud(dLongitud); p.setPrecio(stringToDouble(sPrecio)); } return in; } Producto::Producto() : _sClave(), _sDescripcion("Falta descripcion"), _sUMed("N/A"), _sFam("Sin Familia"), _sClass("Sin clase"), _dVolumen(0.0), _dPrecio(0.0), _dLongitud(0.0) { } Producto::Producto(std::string sClave, std::string sDescripcion, std::string sUMed, std::string sFam, std::string sClass, double dVolumen, double dLongitud, double dPrecio) : _sClave(sClave), _sDescripcion(sDescripcion), _sUMed(sUMed), _sFam(sFam), _sClass(sClass), _dVolumen(dVolumen), _dPrecio(dPrecio), _dLongitud(dLongitud) { } std::string Producto::toString() const { std::ostringstream oss; oss << "Producto: " << _sClave; oss << "\nDescripcion: " << _sDescripcion; oss << "\nUnidad de Medida: " << _sUMed; oss << "\nFamilia: " << _sFam; oss << "\nClase: " << _sClass; oss << "\nVolumen: " << _dVolumen; oss << "\nLongitud: " << _dLongitud; oss << "\nPrecio: " << _dPrecio; return oss.str(); } Main #include <vector> #include <algorithm> #include "Producto.h" std::vector<Producto> vectorProductos; Producto p; while (file >> p) { vectorProductos.push_back(p); } file.close(); ... std::string sClave; std::cout << std::endl << "Clave de producto:\t"; std::cin >> sClave; auto iter = std::find_if(vectorProductos.begin(), vectorProductos.end(), [&](const Producto &p){ return (p.getClave() == sClave); }); if (iter == vectorProductos.end()) { std::cout << "Producto no existe" << std::endl; } else { std::cout << "Producto existe" << std::endl; // use *iter as needed... std::cout << iter->toString() << std::endl; // if you need the index of the found product, you can use: // auto index = std::distance(vectorProductos.begin(), iter); } ...
C++ Delete[] causing program crash [closed]
Closed. This question needs debugging details. It is not currently accepting answers. Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question. Closed 4 years ago. Improve this question My program works fine while I don't have a call to delete[] buf in the destructor. However, when I include it the program crashes at the start of the output. Here are my files. //string.cpp #include "String.h" #include #include extern ofstream csis; String::String() { buf = "\0"; length = 0; } String::String(const char* tar) { int temp = strlen(tar); length = temp; buf = new char[length + 1]; buf[length] = '\0'; for (int i = 0; i < length; i++){ buf[i] = tar[i]; } } String::String(char a) { length = 1; buf = new char[length+1]; buf[length] = '\0'; buf[0] = a; } String::String(int x) { int alloc = x; if (x < 0) { alloc = 0; } buf = new char[alloc+1]; length = x; buf[0] = '\0'; } String::String(const String& a) { length = a.length; buf = new char[length+1]; for (int i = 0; i < length; i++) { buf[i] = a.buf[i]; } } String::String(char a, int x) { buf = new char[x+1]; for (int i = 0; i < x; i++) { buf[i] = a; } buf[x] = '\0'; length = strlen(buf); } String::~String() { delete buf; } String& String::operator=(const String& tar) { buf = new char[tar.length+1]; strcpy(buf, tar.buf); length = tar.length; buf[length] = '\0'; return *this; } String& String::operator=(const char* chr) { buf = (char*)chr; length = int(strlen(chr)); return *this; } String operator+(const String& a, const String& b) { String sum; int size = a.length + b.length; sum.buf = new char[size+1]; sum.length = size; for (int i = 0; i < a.length; i++) { sum.buf[i] = a.buf[i]; } int j = 0; for (int i = a.length; i < size; i++) { sum.buf[i] = b.buf[j]; j++; } sum.buf[size] = '\0'; return sum; } String operator+(const String& tar, const char* c) { String sum; int size = int(strlen(c)) + tar.length; sum.buf = new char[size+1]; sum.length = size; for (int i = 0; i < tar.length; i++) { sum.buf[i] = tar.buf[i]; } int j = 0; for (int i = tar.length; i < size; i++) { sum.buf[i] = c[j]; j++; } sum.buf[size] = '\0'; return sum; } String operator+(const char* c, const String& tar) { String sum; int size = int(strlen(c)) + tar.length; sum.buf = new char[size+1]; sum.length = size; for (int i = 0; i < int(strlen(c)); i++) { sum.buf[i] = c[i]; } int j = 0; for (int i = strlen(c); i < size; i++) { sum.buf[i] = tar.buf[j]; j++; } sum.buf[size] = '\0'; return sum; } String operator+(const String& tar, char c) { String sum; int size = 1 + tar.length; sum.buf = new char[size]; sum.length = size; for (int i = 0; i < tar.length; i++) { sum.buf[i] = tar.buf[i]; } int j = 0; for (int i = tar.length; i < size; i++) { sum.buf[i] = c; j++; } sum.buf[size] = '\0'; return sum; } String operator+(char c, const String& tar) { String sum; int size = 1 + tar.length; sum.buf = new char[size+1]; sum.length = size; for (int i = 0; i < 1; i++) { sum.buf[i] = c; } int j = 0; for (int i = 1; i < size; i++) { sum.buf[i] = tar.buf[j]; j++; } sum.buf[size] = '\0'; return sum; } String& String::operator+=(const String& tar) { String temp = *this; temp = temp + tar; *this = temp; return *this; } String& String::operator+=(const char c) { String temp = *this; temp = temp + c; *this = temp; return *this; } String String::operator+() const { String sum; sum.length = length; sum.buf = new char[sum.length+1]; strcpy(sum.buf, buf); for (int i = 0; i < length; i++) { sum.buf[i] = toupper(buf[i]); } sum.buf[length] = '\0'; return sum; } int operator==(const String & tar, const String& tar2) { int check = 0; if (strcmp(tar.buf, tar2.buf) == 0) { check += 1; } else if (strcmp(tar.buf, tar2.buf) != 0) { check = 0; } return check; } int operator!=(const String& tar, const String& tar2) { int check = 0; if (!(strcmp(tar.buf, tar2.buf) == 0)) { check += 1; } else if (!(strcmp(tar.buf, tar2.buf) != 0)) { check = 0; } return check; } int operator<(const String& a, const String& b) { int check = 0; if (a.length < b.length) { check += 1; } return check; } int operator<=(const String& a, const String& b) { int check = 0; if (a.length <= b.length) { check += 1; } return check; } int operator>(const String& a, const String& b) { int check = 0; if (a.length > b.length) { check += 1; } return check; } int operator>=(const String& a, const String& b) { int check = 0; if (a.length >= b.length) { check += 1; } return check; } char& String::operator[](int x) { int out; if (x >= 0 && x < length) { out = x; } else if (!(x >= 0 && x < length)) { int output = NULL; cout << "ERROR: Invalid Index with [] operator." << endl; csis << "ERROR: Invalid Index with [] operator." << endl; out = NULL; } return buf[out]; } char* operator+(const String& a, int x) { return &a.buf[x]; } char* operator+(int x, const String& a) { return &a.buf[x]; } String String::operator++(int val) { String temp; temp = *this; for (int i = 0; i < temp.length; i++) { temp.buf[i] = temp.buf[i] + 1; } return temp; } String String::operator--(int val) { String temp; temp = *this; for (int i = 0; i < temp.length; i++) { temp.buf[i] = temp.buf[i] - 1; } return temp; } String String::operator++() { String temp = *this; for (int i = 0; i < temp.length; i++) { temp.buf[i] = (temp.buf[i] + 1); } return temp; } String String::operator--() { String temp = *this; for (int i = 0; i < temp.length; i++) { temp.buf[i] = (temp.buf[i] - 1); } return temp; } int String::getLength() { return length; } String String::substr(int a, int b) { String temp = *this; char *fill = new char[b+1]; int i = a; int x = 0; while (x <= b) { fill[i] = temp.buf[i]; i++; x++; } temp.buf = fill; temp.buf[length] = '\0'; return temp; } void String::print() { cout << """"; csis << """"; for (int i = 0; i < length; i++) { cout << buf[i]; csis << buf[i]; } cout << """"; csis << """"; cout << " Length: " << length << endl; csis << " Length: " << length << endl; } ostream& operator<<(ostream& o, const String& tar) { for (int i = 0; i < tar.length; i++) { o << tar.buf[i]; } return o; } Here is string.h //string.h #ifndef _STRING_H #define _STRING_H #include <iomanip> #include <stdlib.h> #include <iostream> using namespace std; class String { protected: int length; char* buf; public: String(); String(const char*); String(char a); String(int x); String(const String&); String(char a, int x); ~String(); // Operator Overload String& operator=(const String& tar); String& operator= (const char*); friend String operator+(const String& a, const String& b); friend String operator+(const String&, const char*); friend String operator+(const char* c, const String& tar); friend String operator+(const String&, char c); friend String operator+(char c, const String& tar); String& operator+=(const String& tar); String& operator+=(const char c); String operator+() const; friend int operator==(const String&, const String&); friend int operator!=(const String&, const String&); friend int operator<(const String&, const String&); friend int operator<=(const String&, const String&); friend int operator>(const String&, const String&); friend int operator>=(const String&, const String&); char& operator[](int); friend char* operator+(const String&, int); friend char* operator+(int, const String&); String operator++(); String operator--(); String operator++(int); String operator--(int); int getLength(); String substr(int a, int b); void print(); friend ostream& operator<<(ostream&, const String&); }; #endif Here is StringDriver.cpp // StringDriver.cpp // MATTHEW BUTNER // ID: 011029756 #include <iostream> #include <fstream> #include <stdlib.h> #include "StringDriver.h" using namespace std; ofstream csis; int main() { csis.open("csis.txt"); test1(); test2(); test3(); test4(); test5(); test6(); test7(); test8(); test9(); test10(); test11(); test12(); test13(); test14(); test15(); test16(); test17(); test18(); test19(); test20(); csis.close(); } void test1() { cout << "1. Testing S1: String default ctor." << endl << endl; csis << "1. Testing S1: String default ctor." << endl << endl; String s1; s1.print(); wait(); } void test2() { cout << "2. Testing S2: String one arg (char *) ctor." << endl << endl; csis << "2. Testing S2: String one arg (char *) ctor." << endl << endl; String s2("ABC"); s2.print(); wait(); } void test3() { cout << "3. Testing S3: String one arg (char) ctor." << endl << endl; csis << "3. Testing S3: String one arg (char) ctor." << endl << endl; String s3('Z'); s3.print(); wait(); } void test4() { cout << "4. Testing S4: String one arg (int) ctor." << endl << endl; csis << "4. Testing S4: String one arg (int) ctor." << endl << endl; String s4(10); s4.print(); wait(); } void test5() { cout << "5. Testing S5, T5: String copy ctor." << endl << endl; csis << "5. Testing S5, T5: String copy ctor." << endl << endl; String s5("Purple Rain"); s5.print(); String t5(s5); t5.print(); wait(); } void test6() { cout << "6. Testing S6: String two arg (char, int) ctor." << endl << endl; csis << "6. Testing S6: String two arg (char, int) ctor." << endl << endl; String s6('*', 10); s6.print(); wait(); } void test7() { cout << "7. Testing S7, T7, U7: String assignment." << endl << endl; csis << "7. Testing S7, T7, U7: String assignment." << endl << endl; String s7("Sally Ride"), t7, u7; t7 = u7 = s7; s7.print(); t7.print(); u7.print(); wait(); } void test8() { cout << "8. Testing S8: String assignment." << endl << endl; csis << "8. Testing S8: String assignment." << endl << endl; String s8("ABC"); s8 = s8; s8.print(); wait(); } void test9() { cout << "9. Testing S9: Implicit type conversion." << endl << endl; csis << "9. Testing S9: Implicit type conversion." << endl << endl; String s9; s9 = "ABC"; s9.print(); wait(); } void test10() { cout << "10. Testing S10, T10, U10: String concatenation." << endl << endl; csis << "10. Testing S10, T10, U10: String concatenation." << endl << endl; String s10("DEF"); String t10('H'); String u10("ABC" + s10 + "G" + t10 + 'I'); u10.print(); String v10('X' + u10); v10.print(); wait(); } void test11() { cout << "11. Testing S11, T11: String concatenation." << endl << endl; csis << "11. Testing S11, T11: String concatenation." << endl << endl; String s11('A'); String t11("BC"); s11 += s11 += t11 += 'D'; s11.print(); t11.print(); wait(); } void test12() { cout << "12. Testing S12, T12: String unary operator." << endl << endl; csis << "12. Testing S12, T12: String unary operator." << endl << endl; String s12("Unary +"); String t12(+s12); s12.print(); t12.print(); s12 = +s12; s12.print(); wait(); } void test13() { cout << "13. Testing S13, T13: String comparison operators." << endl << endl; csis << "13. Testing S13, T13: String comparison operators." << endl << endl; String s13("ABC"), t13("ABCD"); s13.print(); t13.print(); cout << endl; cout << "== " << (s13 == t13 ? "True" : "False") << endl; cout << "!= " << (s13 != t13 ? "True" : "False") << endl; cout << "< " << (s13 < t13 ? "True" : "False") << endl; cout << "<= " << (s13 <= t13 ? "True" : "False") << endl; cout << "> " << (s13 > t13 ? "True" : "False") << endl; cout << ">= " << (s13 >= t13 ? "True" : "False") << endl; csis << endl; csis << "== " << (s13 == t13 ? "True" : "False") << endl; csis << "!= " << (s13 != t13 ? "True" : "False") << endl; csis << "< " << (s13 < t13 ? "True" : "False") << endl; csis << "<= " << (s13 <= t13 ? "True" : "False") << endl; csis << "> " << (s13 > t13 ? "True" : "False") << endl; csis << ">= " << (s13 >= t13 ? "True" : "False") << endl; wait(); } void test14() { cout << "14. Testing S14: Overloaded subscript operator." << endl << endl; csis << "14. Testing S14: Overloaded subscript operator." << endl << endl; String s14("C++ is fun."); for (int i = -1; i <= s14.getLength(); i++) { char& ch = s14[i]; if (ch != '\0') ++ch; } s14.print(); wait(); } void test15() { cout << "15. Testing S15: Pointer notation." << endl << endl; csis << "15. Testing S15: Pointer notation." << endl << endl; String s15("ABCDE"); for(int i = 0; i < s15.getLength(); i++) ++(*(s15+i)); for (int j = 0; j < s15.getLength(); j++) { cout << *(j + s15); csis << *(j + s15); } cout << endl; csis << endl; wait(); } void test16() { cout << "16. Testing S16, T16, U16, V16, W16, X16, Y16, Z16: Increment and decrement operators." << endl << endl; csis << "16. Testing S16, T16, U16, V16, W16, X16, Y16, Z16: Increment and decrement operators." << endl << endl; String s16("ABC"); String t16(++s16); s16.print(); t16.print(); String u16("ABC"); String v16(u16++); u16.print(); v16.print(); String w16("ABC"); String x16(--w16); w16.print(); x16.print(); String y16("ABC"); String z16(y16--); y16.print(); z16.print(); wait(); } void test17() { cout << "17. Testing S17, T17: Substr function." << endl << endl; csis << "17. Testing S17, T17: Substr function." << endl << endl; String s17("All You Need Is Love"), t17; t17 = s17.substr(4, 8); s17.print(); t17.print(); wait(); } void test18() { cout << "18. Testing S18, T18: Output function." << endl << endl; csis << "18. Testing S18, T18: Output function." << endl << endl; String s18("Red-"); String t18("Green-"); String u18("Blue"); cout << s18 << t18 << u18; csis << s18 << t18 << u18; cout << endl; csis << endl; wait(); } void test19() { cout << "19. Testing S19, T19, U19: ReverseString class." << endl << endl; csis << "19. Testing S19, T19, U19: ReverseString class." << endl << endl; ReverseString s19("Computer"); ReverseString t19; t19 = ~s19; s19.print(); t19.print(); ReverseString u19(~~s19); u19.print(); wait(); } void test20() { cout << "20. Testing S20, T20, U20: CaseString class." << endl << endl; csis << "20. Testing S20, T20, U20: CaseString class." << endl << endl; CaseString s20("BaLLooN"); CaseString t20; t20 = s20; s20.print(); t20.print(); CaseString u20(s20); u20.print(); wait(); } void wait() { char buf; cout << endl << "Press any key to continue." << endl; csis << endl << endl; cin.get(buf); } The problem is with the destructor in string.cpp, when I have an empty destructor, everything goes fine and well, but when I include the delete buf, it'll crash the program. Also, here are the other .h and .cpp files: //ReverseString.h #ifndef _REVERSESTRING_H #define _REVERSESTRING_H #include "String.h" #include <iostream> class ReverseString : public String { public: ReverseString(); ReverseString(const ReverseString& tar); ReverseString(const char* c); ReverseString& operator=(const ReverseString&); ReverseString operator~(); }; #endif next file, //ReverseString.cpp #include "ReverseString.h" extern ostream csis; ReverseString::ReverseString() : String() { } ReverseString::ReverseString(const ReverseString& tar) : String(tar) { } ReverseString::ReverseString(const char* c) : String(c) { } ReverseString& ReverseString::operator=(const ReverseString& tar) { length = tar.length; buf = tar.buf; buf[length] = '\0'; return *this; } ReverseString ReverseString::operator~() { ReverseString reverse; reverse.length = length; reverse.buf = new char[length]; int j = length - 1; for (int i = 0; i < length; i++) { reverse.buf[i] = buf[j]; j--; } return reverse; } CaseString.h #ifndef _CASESTRING_H #define _CASESTRING_H #include "String.h" #include <iostream> class CaseString : public String { protected: char* upper; char* lower; public: CaseString(); CaseString(const CaseString& tar); CaseString(const char* c); CaseString& operator=(const CaseString& c); void print(); ~CaseString(); }; #endif CaseString.cpp #include "CaseString.h" #include <fstream> extern ofstream csis; CaseString::CaseString() : String() { } CaseString::CaseString(const CaseString& tar) : String(tar) { upper = tar.upper; lower = tar.lower; buf = tar.buf; length = tar.length; } CaseString::CaseString(const char* c) : String(c) { lower = new char[int(strlen(c))]; upper = new char[int(strlen(c))]; int losize = strlen(c); char* getLow = new char[losize]; for (int i = 0; i < losize; i++) { getLow[i] = tolower(c[i]); } char* getHi = new char[losize]; for (int i = 0; i < losize; i++) { getHi[i] = toupper(c[i]); } lower = getLow; upper = getHi; lower[losize] = '\0'; upper[losize] = '\0'; } CaseString& CaseString::operator=(const CaseString& tar) { if (&tar != this) { String::operator=(tar); buf = tar.buf; length = tar.length; lower = tar.lower; upper = tar.upper; } return *this; } void CaseString::print() { cout << "\"" << buf << "\"" << " " << "Length = " << length << " |" << "Lower = " << lower << " |" << "Upper = " << upper << endl; csis << "\"" << buf << "\"" << " |" << "Length = " << length << " |" << "Lower = " << lower << " |" << "Upper = " << upper << endl; } CaseString::~CaseString() { }
There are several issues that I see. The main problem is that you sometimes assign a pointer to a character string to buf (your default constructor is one such place, and there is at least one other). This is a pointer you do not want to delete. You need to either always allocate memory for buf, or have some way to tell if you own the pointer and it should be deleted. The other issue is that since you use new [], you need to use delete [] buf in your destructor. In your copy constructor, you do not copy the nul byte at the end of the coped buffer.
How to insert c++ find into a while loop?
I use a while loop with the find function in c++ but I need to use the position found like the condition of the while loop but Visual Studio shome me An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occured in Test.exe Additional information: External component has thrown an exception. I use this code: int dim=myString.length(); while (dim>=0) { size_t pos1 = myString.find("<article"); size_t pos2 = myString.find("</article>"); std::string buf = myString.substr(pos1, pos2 - pos1 + 10); myString = myString.substr(pos2 + 10); ofstream myfile("body.txt"); if (myfile.is_open()) { myfile << myString; myfile.close(); } else cout << "Unable to open file"; //cout << myString << endl; ptree xmlTree; string title[1000]; int j = 0; try { stringstream ss; ss << buf; read_xml(ss, xmlTree); const ptree & formats = xmlTree.get_child("article", empty_ptree()); BOOST_FOREACH(const ptree::value_type & f, formats) { string at = f.first + ATTR_SET; const ptree & attributes = f.second.get_child("<xmlattr>", empty_ptree()); //cout << "Extracting attributes from " << at << ":" << endl; BOOST_FOREACH(const ptree::value_type &v, attributes) { string first = v.first.data(); //cout << "First: " << v.first.data() << " Second: " << v.second.data() << endl; if (first == "title") { title[j] = v.second.data(); j++; } } } for (int a = 0; a < j; a++) { cout << title[a] << endl; } } catch (xml_parser_error &e) { cout << "Failed to read config xml " << e.what() << endl; } catch (...) { cout << "Failed to read config xml with unknown error" << endl; } dim = dim - pos2; } what is the problem?
I resolve my problem thanks to the help of PaulMcKenzie. I modify my code to insert a boolean variable and to control if pos1 and pos2 find the correct string which are <article and </article>. This is the code: int dim = myString.length(); boolean in=true; while (in==true) { size_t pos1 = myString.find("<article"); size_t pos2 = myString.find("</article>"); if (pos1 != std::string::npos && pos2 != std::string::npos) { std::string buf = myString.substr(pos1, pos2 - pos1 + 10); myString = myString.substr(pos2 + 10); ofstream myfile("body.txt"); if (myfile.is_open()) { myfile << myString; myfile.close(); } else cout << "Unable to open file"; //some code dim = dim - myString.length(); in = true; } else { in = false; cout << " - - - - - - - - - - " << endl; } }
C1001 Compiling Error On Creation Of Class Object
When I Create An Instance of the following class using Game newGame; it throws a c1001 error stating that there was a compiler error. game.h: #pragma once #include <iostream> #include <fstream> #include <string> #include <vector> #include <conio.h> #include "cls.h" #include "explode.h" using namespace std; class Game { private: explode EXP; CLS cls; string _SaveGame, _DIRECTORY; int _GAMEDATA[500]; string _DATATITLES[500] = { "Ticks", "Dwarves", "Grain Mills", "Lumber Mills", "Mines", "Grain Workers", "Lumber Workers", "Mine Workers", "Grain Mill Experts", "Lumber Mill Experts", "Mine Experts" }; public: void CS() { cls.clear(); } void SetSaveName(string SaveName) { _SaveGame = SaveName; } void init(string directory) { _DIRECTORY = directory; cout << "Init Game" << endl; CS(); ofstream gameSave; gameSave.open(_DIRECTORY + _SaveGame + ".save", ofstream::out | ofstream::app); cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save"; if (!gameSave.good()) { // Write New Data To File cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save"; gameSave.flush(); gameSave << "0\n"; // TICKS gameSave.flush(); gameSave << "7\n"; // Dwarves gameSave.flush(); gameSave << "1\n"; // Grain Mills gameSave.flush(); gameSave << "1\n"; // Lumber Mill gameSave.flush(); gameSave << "1\n"; // Mine gameSave.flush(); gameSave << "2\n"; // Grain Mill Workers gameSave.flush(); gameSave << "2\n"; // Lumber Mill Workers gameSave.flush(); gameSave << "3\n"; // Mine Workers gameSave.flush(); gameSave << "1\n"; // Grain Mill Experts gameSave.flush(); gameSave << "1\n"; // Lumber Mill Experts gameSave.flush(); gameSave << "1\n"; // Mine Experts gameSave.flush(); gameSave << "ENDFILE"; gameSave.flush(); } else { // Read Data From File loadGame(_SaveGame); } bool GameLoop = true; while (GameLoop) { // Begin Game Loop Instance printData(); string in; bool parseDataLoop = 1; while (parseDataLoop) { in = getData(); int parseDataInt = parseData(in); if (parseDataInt == 1) { GameLoop = 0; saveGame(); exit(0); } else if (parseDataInt == 2) { _getch(); } else { parseDataLoop = 0; } } saveGame(); } } void GameTick() { _GAMEDATA[0] += 1; // Number Of Game Ticks } void printData() { CS(); for (int i = 0; i < 500; i++) { if (_GAMEDATA[i] != NULL) { cout << _DATATITLES[i] << " : " << _GAMEDATA[i]; } } } string getData() { string DATA; cin >> DATA; return DATA; } int parseData(string input) { int quit = 0; if (input == "help") { // Print List Of Commands And Descriptions: cout << "List Of All Available Commands:" << endl; cout << "help : Shows A List Of All Available Commands" << endl; cout << "tick : Makes Game Progress One Tick" << endl; cout << "tick.NUM : Makes Game Progress NUM Tick(s)" << endl; cout << "quit : Saves Game And Terminates Program" << endl; quit = 2; } else if (input == "quit") { quit = 1; } else if (input == "tick") { // Skip One Tick GameTick(); } else if (find(input, '.')) { vector<string> output; output = EXP.explodeStuff(input, '.'); if (output[0] == "tick") { if (isInterger(output[1])) { for (int i = 0; i < stoi(output[1]); i++) { GameTick(); } } else { cout << "ERROR: tick." << output[1] << ", is not vaid please use numbers not letters." << endl; quit = 2; } } } else { cout << "ERROR: Invalid Command Please type \"help\" To See A List Of Available Commands." << endl; quit = 2; } return quit; } void loadGame(string saveGame) { ifstream inData; string temp; inData.open(_DIRECTORY + saveGame + ".cod"); if (inData.good()) { for (int i = 0; i < 500; i++) { getline(inData, temp); if (temp == "ENDFILE") { break; } if (temp != "") { _GAMEDATA[i] = stoi(temp); } } inData.close(); } } void saveGame() { // Update Data in file ofstream gameSave(_DIRECTORY + _SaveGame + ".save"); gameSave.clear(); for (int i = 0; i < 500; i++) { if (_GAMEDATA[i] != NULL) { gameSave << _GAMEDATA[i]; } } gameSave << "\nENDFILE"; } bool find(string input, char find) { bool RETURN = 0; for each (char CHAR in input) { if (CHAR == find) { RETURN = 1; break; } } return RETURN; } inline bool isInterger(const std::string & s) { if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false; char* p; strtol(s.c_str(), &p, 10); return (*p == 0); } }; main.cpp: #include <iostream> #include <fstream> #include <string> #include <vector> #include "game.h" #include "programSettings.h" #include "cls.h" #include "explode.h" // Adds explode(string input, char delimeter), and explodePrint(vector<string> input) using namespace std; string _DIRECTORY = (string)getenv("APPDATA") + "/cityOfDwarves/"; vector<int> _SETTINGS; // Array To Hold All Settings In The SETTINGS.cod File int SettingsConfigured; explode EXP; CLS cls; int main() { SetConsoleTitle("CityOfDwarves"); programSettings pSet(_DIRECTORY); _SETTINGS = pSet.readSettings(); if (_SETTINGS.size() > 0) { SettingsConfigured = _SETTINGS[0]; } else { SettingsConfigured = 0; } if (!SettingsConfigured) { pSet.setSettings(); } cout << "Settings Configured" << endl; cls.clear(); cout << "Please Enter a Save Name:" << endl; string SaveName; cin >> SaveName; cout << "Using: " << SaveName << ", As The Current Save File." << endl; // Begin Game Loop Game mainGame; mainGame.SetSaveName(SaveName); mainGame.init(_DIRECTORY); char i; cin >> i; return 0; } Complete Error Code: Severity Code Description Project File Line Error C1001 An internal error has occurred in the compiler. CityOfDwarves C:\Users\Daniel\Documents\Visual Studio 2015\Projects\CityOfDwarves\CityOfDwarves\main.cpp 1
C++ simple string replace, non complicated code, but producing crazy error
First, thank for you all your help! The error I am getting is: Unhandled exception at 0x7c812afb (kernel32.dll) in Readerboard.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0012f8a8.. I have found the problem to be with this line: str.replace(str.find(sought), sought.size(), replacement); It is located in this procedure: void DisplayMessages() { ifstream myReadFile; string str; static string myMessages[10]; static int i; // of course my famous i static int MyPosition; string sought; string replacement; myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in); i = 0; //the start of my array sought = "</td>"; // value that I want to replace with nothing replacement.clear(); if(!myReadFile) // is there any error? { cout << "Error opening the file! Aborting…\n"; exit(1); } if (myReadFile.is_open()) { cout << endl; while (!myReadFile.eof()) { getline(myReadFile, str); if (str == "<tr>") { myReadFile.seekg(4,ios::cur); getline(myReadFile, str); str.replace(str.find(sought), sought.size(), replacement); cout << str; myMessages[i]=str; i++; } } } i=0; while (i < 10) { cout << i << ") " << myMessages[i] << endl; i++; if (myMessages[i]=="") { break; } } myReadFile.close(); mainMenu(); } The whole cpp file is displayed below: #include <iostream> #include <string> #include <fstream> using namespace std; void mainMenu(); void DisplayMessages(); void AddMessage(); void DeleteMessage(); void EditMessage(); void RunTests(); void CheckFile(); void CreateHtmlFile(string myMessages[10]); /* #define MIN 1 #define MAX 100 #define TRUE 1 #define FALSE 0 */ int main() { cout << endl; cout << endl; cout << "Hello Andrew.\n"; cout << "First you need some sort of menu.\n"; mainMenu(); return 0; } void mainMenu() { int Command; cout << endl; cout << endl; cout << endl; cout << "What would you like to do?\n"; // cout << "1) Check that tests work!\n"; // cout << "2) Check that the file exists\n"; cout << "3) Display Messages\n"; // cout << "4) Edit a message\n"; // cout << "5) Add a message\n"; // cout << "6) Delete a message\n"; cout << "7) Exit\n"; cout << "Enter a number: "; cin >> Command; if (Command == 3) { DisplayMessages(); } if (Command == 7) { cout << "Exiting..."; exit(EXIT_SUCCESS); } if (Command == 6) { DisplayMessages(); } } void DisplayMessages() { ifstream myReadFile; string str; static string myMessages[10]; static int i; // of course my famous i static int MyPosition; string sought; string replacement; myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in); i = 0; //the start of my array sought = "</td>"; // value that I want to replace with nothing replacement.clear(); if(!myReadFile) // is there any error? { cout << "Error opening the file! Aborting…\n"; exit(1); } if (myReadFile.is_open()) { cout << endl; while (!myReadFile.eof()) { getline(myReadFile, str); if (str == "<tr>") { myReadFile.seekg(4,ios::cur); getline(myReadFile, str); str.replace(str.find(sought), sought.size(), replacement); cout << str; myMessages[i]=str; i++; } } } i=0; while (i < 10) { cout << i << ") " << myMessages[i] << endl; i++; if (myMessages[i]=="") { break; } } myReadFile.close(); mainMenu(); } void AddMessage() { } /* void DeleteMessage() { ifstream myReadFile; string str; static string myMessages[10]; static int i; // of course my famous i static int MyPosition; string sought; string replacement; static int Command; myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in); i = 0; //the start of my array sought = "</b></td>"; // value that I want to replace with nothing replacement.clear(); if(!myReadFile) // is there any error? { cout << "Error opening the file! Aborting…\n"; exit(1); } if (myReadFile.is_open()) { cout << endl; while (!myReadFile.eof()) { getline(myReadFile, str); if (str == "<tr>") { myReadFile.seekg(7,ios::cur); getline(myReadFile, str); str.replace(str.find(sought), sought.size(), replacement); myMessages[i]=str; i++; } } } i=0; while (i < 10) { cout << i << ") " << myMessages[i] << endl; i++; if (myMessages[i]=="") { break; } } myReadFile.close(); cout << "Enter the number of the message you would like to delete?\n"; cout << "Or enter 11 to go back to the main menu.\n"; cin >> Command; while (Command >= 12) { cout << "Invalid number, try again!\n"; cout << endl; cout << "Enter the number of the message you would like to delete?\n"; cout << "Or enter 11 to go back to the main menu.\n"; cin >> Command; } if (Command == 11) { mainMenu(); } myMessages[Command].clear(); //clear the string //now rebuild the htm file with the new array CreateHtmlFile(myMessages); } void EditMessage() { } void RunTests() { } void CheckFile() { } void CreateHtmlFile(string myMessages[]) { } //File.seekg(-5); moves the inside pointer 5 characters back //File.seekg(40); moves the inside pointer 40 characters forward //tellg() Returns an int type, that shows the current position of the inside-pointer for reading //tellp() same as above but for writing //seekp() just like seekg() but for writing */ Please help I am so stumped!
str.replace(str.find(sought), sought.size(), replacement); is wrong when str.find() doesn't find what it's looking for. str.find() will return str::npos, which will not be a valid location in the string. Hence, the call to replace fails with the index out of range exception you're seeing. Change that to: std::size_t foundIndex = str.find(sought); if (foundIndex != str.npos) str.replace(foundIndex, sought.size(), replacement); else std::cout << "Oops.. didn't find " << sought << std::endl; and let us know if that helps you. EDIT: You might also want to consider using boost::algorithm::replace_all from the Boost String Algorithms Library
A complete function for replacing strings: std::string ReplaceString(std::string subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } return subject; } If you need performance, here is an optimized function that modifies the input string, it does not create a copy of the string: void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } } Tests: std::string input = "abc abc def"; std::cout << "Input string: " << input << std::endl; std::cout << "ReplaceString() return value: " << ReplaceString(input, "bc", "!!") << std::endl; std::cout << "ReplaceString() input string not modified: " << input << std::endl; ReplaceStringInPlace(input, "bc", "??"); std::cout << "ReplaceStringInPlace() input string modified: " << input << std::endl; Output: Input string: abc abc def ReplaceString() return value: a!! a!! def ReplaceString() input string not modified: abc abc def ReplaceStringInPlace() input string modified: a?? a?? def