Using stringstream: Only working for first value - c++

I am trying to use stringstream with peek() and get(n). It is only working for the first value, Name, and then gives empty values for everything except weight, which gives 0 (when printing out with cout).
stringstream ss;
ss.str("John Smith, Toyota, 160, brown blue, orange");
//Extract into these variables:
string Name = "" ;
string car = "" ;
int weight = 0;
string hairColor = "";
string eyeColor = "";
string favoriteColor = "";
while (ss.peek () != ',')
{
char temp;
ss. get(temp);
Name += temp;
}
while (ss.peek () != ',')
{
char temp;
ss. get(temp);
car += temp;
}
while (ss.peek () != ',')
{
char temp;
ss. get(temp);
weight += temp;
}
while (ss.peek () != ',')
{
char temp;
ss. get(temp);
hairColor += temp;
}
while (ss.peek () != ',')
{
char temp;
ss. get(temp);
eyeColor += temp;
}
while (ss.peek () != ',')
{
char temp;
ss. get(temp);
favoriteColor += temp;
}
cout << "Name is: " << Name << endl;
cout << "car is: " << car << endl;
cout << "weight is: " << weight << endl;
cout << "Hair color is: " << hairColor << endl;
cout << "Eye color is: " << eyeColor << endl;
cout << "Favorite color is: " << favoriteColor << endl;
What is the problem here?

The immediate problem is that after the first loop the continuation condition is false, so none of the following loops, with the same continuation condition, do anything.
However, the usual way to extract an item is to use the getline function, where you can specify an arbitrary delimiter character instead of newline.
Doing this properly is a bit involved:
#include <iomanip> // std::setw
#include <iostream>
#include <stdexcept> // std::runtime_error, std::exception
#include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS
#include <sstream> // std::istringstream
using namespace std;
auto fail( const string& s ) -> bool { throw runtime_error( s ); }
auto get_string( istream& stream, const char delimiter = ',' )
-> string
{
while( stream.peek() == ' ' )
{
stream.get();
}
string result;
getline( stream, result, delimiter )
|| fail( "get_string: failed to extract text" );
return result;
}
template< class Type >
auto get( istream& stream, const char delimiter = ',' )
-> Type
{
istringstream conversion_stream( get_string( stream, delimiter ) );
Type result;
conversion_stream >> result
|| fail( "get: failed to convert text to value" );
return result;
}
template<>
auto get<string>( istream& stream, const char delimiter )
-> string
{ return get_string( stream, delimiter ); }
template< class Type >
void display( const char name[], const Type& value )
{
cout << setw( 15 ) << name << " = " << value << endl;
}
#define DISPLAY( x ) display( #x, x )
void cpp_main()
{
istringstream data_stream( "John Smith, Toyota, 160, brown, blue, orange" );
const auto name = get<string>( data_stream );
const auto car = get<string>( data_stream );
const auto weight = get<int>( data_stream );
const auto hairColor = get<string>( data_stream );
const auto eyeColor = get<string>( data_stream );
const auto favoriteColor = get<string>( data_stream );
DISPLAY( name );
DISPLAY( car );
DISPLAY( weight );
DISPLAY( hairColor );
DISPLAY( eyeColor );
DISPLAY( favoriteColor );
}
auto main() -> int
{
try
{
cpp_main();
return EXIT_SUCCESS;
}
catch( const exception& x )
{
cerr << "!" << x.what() << endl;
}
return EXIT_FAILURE;
}

ss.peek() == ',' becomes true at the end of the first loop. Use std::getline so you won't have this problem:
if (getline(ss, Name) && getline(ss, car) && ss >> weight && getline((ss >> std::ws).ignore(), hairColor))
{
cout << "Name is: " << Name << endl;
cout << "car is: " << car << endl;
cout << "weight is: " << weight << endl;
cout << "Hair color is: " << hairColor << endl;
cout << "Eye color is: " << eyeColor << endl;
cout << "Favorite color is: " << favoriteColor << endl;
}

Related

Parsing CSV into Struct Array

I am trying to parse CSV into Array of structures. Delimiter is ';'. If you look into the code it seems that I filled only first element of the array out of nine that is 9 lines are in my CSV right now. Remaining elements of the array are just 0. Anyone got some advice? Thanks
fileTO.open("imput.csv", ios_base :: app);
fileFROM.open("imput.csv", ios_base :: app);
//IntoCsvThruConsole();
// array of structures from csv
string line;
string sID, stype, scategory, samount, sdate;
int lines = CountExistingLines();
Properties * structure = new Properties[lines];
int counter = 0;
int position = 0;
while (getline(fileFROM, line))
{
sID = "";
samount = "";
for (int i = 0; i < line.size(); i++)
{
if (line[i] == ';')
{
position++;
continue;
}
switch (position)
{
case 0 : sID = sID + line[i];
break;
case 1 : structure[counter].type = structure[counter].type + line[i];
break;
case 2 : structure[counter].category = structure[counter].category + line[i];
break;
case 3 : samount = samount + line[i];
break;
case 4 : structure[counter].date = structure[counter].date + line[i];
break;
}
}
structure[counter].ID = atoi(sID.c_str());
structure[counter].amount = atoi(samount.c_str());
cout << "ID zaznamu: " << structure[counter].ID << endl;
cout << "Typ: " << structure[counter].type << endl;
cout << "Kategorie: " << structure[counter].category << endl;
cout << "Castka: " << structure[counter].amount << endl;
cout << "Datum: " << structure[counter].date << endl;
counter++;
}
delete[] structure;
I have globally initialized struct correctly and also fstreams. Hope it is enough. Thanks
enter image description here
I recommend using Boost.Spirit for such parsing tasks.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/home/x3.hpp>
struct Date
{
int day;
int month;
int year;
};
std::ostream& operator<<(std::ostream& os, Date const &d)
{
os << d.day << '/' << d.month << '/' << d.year;
return os;
}
BOOST_FUSION_ADAPT_STRUCT(
Date,
day, month, year)
struct Properties
{
int ID;
std::string type;
std::string category;
int amount;
Date date;
};
BOOST_FUSION_ADAPT_STRUCT(
Properties,
ID, type, category, amount, date)
std::vector<Properties> parse(std::string const &input)
{
auto iter = input.begin();
using namespace boost::spirit::x3;
auto name = rule<class name, std::string>{}
= lexeme[alpha >> *alpha];
auto date = rule<class date, Date>{}
= int_ > '/' > int_ > '/' > int_;
std::vector<Properties> result;
bool r = phrase_parse(iter, input.end(),
(int_ > ';' > name > ';' > name > ';' > int_ > ';' > date) % eol,
space - eol, result);
if (!r)
{
std::string rest(iter, input.end());
throw std::invalid_argument("Parsing failed at " + rest);
}
return result;
}
int main()
{
// This could be a file instead with std::ifstream
std::istringstream input;
input.str(
"1;TypeA;CategoryA;10;05/12/2017\n"
"2;TypeB;CategoryA;21;04/12/2017\n"
"3;TypeB;CategoryB;19;01/12/2017\n"
"4;TypeA;CategoryA; 6;20/11/2017\n");
std::vector<Properties> entry = parse(input.str());
for (auto e : entry)
{
std::cout << "Found the following entries:\n"
<< " ID: " << e.ID << "\n"
<< " Type: " << e.type << "\n"
<< " Category: " << e.category << "\n"
<< " Amount: " << e.amount << "\n"
<< " Date: " << e.date << "\n";
}
}
Live example

C++ Confused about functions and vectors

Hopefully this will be my last question for a while.
I'm a little confused as to why my function isn't working. Here is my code (I'll explain a little bit more afterwards):
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
class Inventory {
public:
void SetSumInv(int prcInDllrs, int individualquantity) {
priceInDollars = priceInDollars + (prcInDllrs * individualquantity);
totalInvPriceInDollars = totalInvPriceInDollars + priceInDollars;
}
void SetItemPrice(int whatever) {
itemsPrice = whatever;
}
void SetName(string nm)
{
name = nm;
};
void SetQuantity(int qnty)
{
quantity = qnty;
};
void SetAuthor(string athr) {
author = athr;
}
void SetExpiration(string expir)
{
expiration = expir;
};
virtual void Print(){
cout << name << " x" << quantity << " for: $" << itemsPrice; //" (Expires: " << expiration << ")";
if (expiration.size() != 0) {
cout << " (Expires: " << expiration << ")" << endl;
}
else {
cout << " (Author: " << author << ")" << endl;
}
}
void PrintInventory(vector<Inventory*> inventory) {
unsigned int i = 0;
if (inventory.size() == 0) {
cout << "No items to print." << endl;
}
else {
for (i = 0; i<inventory.size(); ++i) {
cout << i << " - ";
inventory.at(i)->Print();
}
cout << "Total inventory value: " << priceInDollars;
}
return;
}
void AddItemToInventory()
{
}
vector<Inventory*> AddProduceToInventory(vector<Inventory*> inventory)
{
Inventory* prdc;
string usrInptName = "";
string usrInptQntyStr = "";
istringstream inSS;
istringstream inDD;
int usrInptQnty = 0;
string usrInptExpr = "";
string usrInptPrcStr = "";
int usrInptPrc = 0;
int ItemCost = 0;
cout << "Enter name of new produce: ";
getline(cin, usrInptName);
SetName(usrInptName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
SetQuantity(usrInptQnty);
cout << "Enter expiration date: ";
getline(cin, usrInptExpr);
SetExpiration(usrInptExpr);
cout << "Enter the price per item: $";
getline(cin, usrInptPrcStr);
inDD.str(usrInptPrcStr);
inDD >> usrInptPrc;
inDD.clear();
SetItemPrice(usrInptPrc);
ItemCost = (usrInptPrc * usrInptQnty);
prdc = new Inventory;
prdc->SetName(usrInptName);
prdc->SetQuantity(usrInptQnty);
prdc->SetExpiration(usrInptExpr);
prdc->SetSumInv(usrInptPrc, usrInptQnty);
prdc->SetItemPrice(usrInptPrc);
inventory.push_back(prdc);
return inventory;
}
void AddBookToInventory()
{
}
vector<Inventory*> AddBookToInventory(vector<Inventory*> inventory) {
Inventory* prdct;
string usrInptName = "";
string usrInptQntyStr = "";
istringstream inSS;
int usrInptQnty = 0;
string usrInptAthr = "";
string usrInptPrcStr = "";
int usrInptPrc = 0;
istringstream inDD;
int sum = 0;
int ItemCost = 0;
cout << "Enter name of new book: ";
getline(cin, usrInptName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
cout << "Enter author: ";
getline(cin, usrInptAthr);
cout << "Enter the price per item: $";
getline(cin, usrInptPrcStr);
inDD.str(usrInptPrcStr);
inDD >> usrInptPrc;
inDD.clear();
ItemCost = (usrInptPrc * usrInptQnty);
prdct = new Inventory;
prdct->SetName(usrInptName);
prdct->SetQuantity(usrInptQnty);
prdct->SetSumInv(usrInptPrc, usrInptQnty);
prdct->SetAuthor(usrInptAthr);
prdct->SetItemPrice(usrInptPrc);
inventory.push_back(prdct);
return inventory;
}
void UpdateItemQtyInventory()
{}
//This is the update function in which we can change how many items a certain purchase has
vector<Inventory*> UpdateItemQtyInInventory(vector<Inventory*> inventory) {
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
istringstream inSS;
string usrInptQntyStr = "";
int usrInptQnty = 0;
if (inventory.size() == 0) {
cout << "No items to update." << endl;
}
else {
PrintInventory(inventory);
do {
cout << "Update which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
cout << "Enter new quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
inventory.at(usrIndexChoice)->SetQuantity(usrInptQnty);
}
return inventory;
}
void RemoveItemFromInventory()
{}
//Here we will be removing an entire item from the inventory
vector<Inventory*> RemoveItemFromInventory(vector<Inventory*> inventory) {
istringstream inSS;
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
string usrInptQntyStr = "";
if (inventory.size() == 0) {
cout << "No items to remove." << endl;
}
else {
PrintInventory(inventory);
do {
cout << "Remove which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
inventory.erase(inventory.begin() + usrIndexChoice);
}
return inventory;
}
void GetTotalValueAsPrice()
{
}
protected:
string name;
int quantity = 0;
int priceInDollars = 0;
int totalCost = 0;
int itemsPrice = 0;
string expiration;
string author;
private:
int totalInvPriceInDollars = 0;
};
int main() {
vector<Inventory*> INVENTORY;
string usrInptOptn = "default";
string usrInptOptn2 = "default";
Inventory update;
while (true) {
// Get user choice
cout << "\nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
getline(cin, usrInptOptn);
// Process user choice
if (usrInptOptn.size() == 0) {
continue;
}
else if (usrInptOptn.at(0) == 'p') {
update.PrintInventory(INVENTORY); //Different!
}
else if (usrInptOptn.at(0) == 'a') {///I don't know what the difference is between the three slashes and the two, but they are different!
cout << "\nEnter (b)ook or (p)roduce: ";
getline(cin, usrInptOptn2);
if (usrInptOptn2.at(0) == 'b') {
INVENTORY = update.AddBookToInventory(INVENTORY); //Supposed to look like: INV = AddItem...(INV);
}
else if (usrInptOptn2.at(0) == 'p') {
INVENTORY = update.AddProduceToInventory(INVENTORY);
}
else
{
continue;
}
}
else if (usrInptOptn.at(0) == 'u') {
INVENTORY = update.UpdateItemQtyInInventory(INVENTORY);
}
else if (usrInptOptn.at(0) == 'r') {
INVENTORY = update.RemoveItemFromInventory(INVENTORY);
}
else if (usrInptOptn.at(0) == 'q') {
cout << "\nGood bye." << endl;
break;
}
}
return 0;
}
So now. In my class Inventory, public: void SetSumInv, what this program does is it gets the user input, and tallies everything up, so when it prints, it is supposed to print the inventory and afterwards it is supposed to print the sum of the inventory value (in dollars). I've tried running this, and it won't print the sum of the inventory value. What is wrong here? I can't figure this out.
Thanks!
After dissecting your code; it took me considerable amount of time to clean some of it up. I did not have time to search for your bug, but what I was able to do was clean up your class a little bit so that it is friendlier to read. I made a couple of modifications to some of your class's function calls which are explained in the comments. I also removed all of the empty functions you had declared within your class. I also changed the look or feel of the classes naming conventions (this is user preference only)
Inventory.h
#ifndef INVENTORY_H
#define INVENTORY_H
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
class Inventory {
protected:
std::string m_strName;
std::string m_strExpiration;
std::string m_strAuthor;
int m_quantity;
int m_priceInDollars;
int m_totalCost;
int m_itemsPrice;
private:
int m_totalInvPriceInDollars;
public:
Inventory(); // Default Constructor
void setName( const std::string& nm );
void setAuthor( const std::string& athr );
void setExpiration( const std::string& expir );
void setSumInv( int prcInDllrs, int individualquantity );
void setItemPrice( int whatever );
void setQuantity( int qnty );
virtual void print();
void printInventory( std::vector<Inventory*>& inventory );
// I changed these methods to pass by reference opposed to returning from function call
void addProduceToInventory( std::vector<Inventory*>& inventory );
void addBookToInventory( std::vector<Inventory*>& inventory );
void updateItemQtyInInventory( std::vector<Inventory*>& inventory );
void removeItemFromInventory( std::vector<Inventory*>& inventory );
}; // Invenotory
#endif // INVENTORY_H
Inventory.cpp
#include "Inventory.h"
// ----------------------------------------------------------------------------
// Inventory()
Inventory::Inventory() :
m_quantity( 0 ),
m_itemsPrice( 0 ),
m_priceInDollars( 0 ),
m_totalCost( 0 ),
m_totalInvPriceInDollars( 0 ) {
} // Inventory
// ----------------------------------------------------------------------------
// setSumInv()
void Inventory::setSumInv( int prcInDllrs, int individualquantity ) {
m_priceInDollars = m_priceInDollars + (prcInDllrs * individualquantity);
m_totalInvPriceInDollars = m_totalInvPriceInDollars + m_priceInDollars;
} // setSumInv
// ----------------------------------------------------------------------------
// setItemPrice()
void Inventory::setItemPrice( int whatever ) {
m_itemsPrice = whatever;
} // setItemPrice
// ----------------------------------------------------------------------------
// setQuantity()
void Inventory::setQuantity( int qnty ) {
m_quantity = qnty;
} // setQuantity
// ----------------------------------------------------------------------------
// setName()
void Inventory::setName( const std::string& strName ) {
m_strName = strName;
} // setName
// ----------------------------------------------------------------------------
// setAuthor()
void Inventory::setAuthor( const std::string& strAuthor ) {
m_strAuthor = strAuthor;
} // setAuthor
// ----------------------------------------------------------------------------
// setExpiration()
void Inventory::setExpiration( const std::string& strExpir ) {
m_strExpiration = strExpir;
} // setExpiration
// ----------------------------------------------------------------------------
// print()
void Inventory::print() {
std::cout << m_strName << " x" << m_quantity << " for: $" << m_itemsPrice; //" (Expires: " << expiration << ")";
if ( m_strExpiration.size() != 0 ) {
std::cout << " (Expires: " << m_strExpiration << ")" << std::endl;
} else {
std::cout << " (Author: " << m_strAuthor << ")" << std::endl;
}
} // print
// ----------------------------------------------------------------------------
// printInventory()
void Inventory::printInventory( std::vector<Inventory*>& vInventory ) {
unsigned int i = 0;
if ( vInventory.size() == 0) {
std::cout << "No items to print." << std::endl;
} else {
for ( i = 0; i < vInventory.size(); ++i ) {
std::cout << i << " - ";
vInventory.at(i)->print();
}
std::cout << "Total inventory value: " << m_priceInDollars;
}
} // printInventory
// ----------------------------------------------------------------------------
// addProduceToInventory()
void Inventory::addProduceToInventory( std::vector<Inventory*>& vInventory ) {
std::string usrInptName = "";
std::string usrInptQntyStr = "";
std::istringstream inSS;
std::istringstream inDD;
int usrInptQnty = 0;
std::string usrInptExpr = "";
std::string usrInptPrcStr = "";
int usrInptPrc = 0;
int itemCost = 0;
std::cout << "Enter name of new produce: ";
getline( std::cin, usrInptName );
setName( usrInptName );
std::cout << "Enter quantity: ";
std::getline( std::cin, usrInptQntyStr );
inSS.str( usrInptQntyStr );
inSS >> usrInptQnty;
inSS.clear();
setQuantity( usrInptQnty );
std::cout << "Enter expiration date: ";
getline( std::cin, usrInptExpr );
setExpiration( usrInptExpr );
std::cout << "Enter the price per item: $";
getline( std::cin, usrInptPrcStr );
inDD.str( usrInptPrcStr );
inDD >> usrInptPrc;
inDD.clear();
setItemPrice( usrInptPrc );
itemCost = usrInptPrc * usrInptQnty;
Inventory* pInv = nullptr; // Initialize Pointers to nullptr
pInv = new Inventory; // Using New Memory (Dyanamic) - Where Is This Being Deleted?
pInv->setName( usrInptName );
pInv->setQuantity( usrInptQnty );
pInv->setExpiration( usrInptExpr );
pInv->setSumInv( usrInptPrc, usrInptQnty );
pInv->setItemPrice(usrInptPrc);
vInventory.push_back( pInv );
} // addProduceToInventory
// ----------------------------------------------------------------------------
// addBookToInventory()
void Inventory::addBookToInventory( std::vector<Inventory*>& inventory) {
std::string usrInptName = "";
std::string usrInptQntyStr = "";
std::istringstream inSS;
int usrInptQnty = 0;
std::string usrInptAthr = "";
std::string usrInptPrcStr = "";
int usrInptPrc = 0;
std::istringstream inDD;
int sum = 0;
int itemCost = 0;
std::cout << "Enter name of new book: ";
getline( std::cin, usrInptName );
std::cout << "Enter quantity: ";
getline( std::cin, usrInptQntyStr );
inSS.str( usrInptQntyStr );
inSS >> usrInptQnty;
inSS.clear();
std::cout << "Enter author: ";
getline( std::cin, usrInptAthr );
std::cout << "Enter the price per item: $";
getline( std::cin, usrInptPrcStr );
inDD.str( usrInptPrcStr );
inDD >> usrInptPrc;
inDD.clear();
itemCost = usrInptPrc * usrInptQnty;
Inventory* pInv = nullptr; // Initialize pointers to nullptr;
pInv = new Inventory; // Using New Memory (Dyanamic) - Where Is This Being Deleted?
pInv->setName( usrInptName );
pInv->setQuantity( usrInptQnty );
pInv->setSumInv( usrInptPrc, usrInptQnty );
pInv->setAuthor( usrInptAthr );
pInv->setItemPrice( usrInptPrc );
inventory.push_back( pInv );
} // addBookToInventory
// ----------------------------------------------------------------------------
// updateItemQtyInInventory()
// This is the update function in which we can change how many items a certain purchase has
void Inventory::updateItemQtyInInventory( std::vector<Inventory*>& vInventory ) {
std::string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
std::istringstream inSS;
std::string usrInptQntyStr = "";
int usrInptQnty = 0;
if ( vInventory.size() == 0 ) {
std::cout << "No items to update." << std::endl;
} else {
printInventory( vInventory );
do {
std::cout << "Update which item #: ";
getline( std::cin, usrIndexChoiceStr );
inSS.str( usrIndexChoiceStr );
inSS >> usrIndexChoice;
inSS.clear();
} while ( !(usrIndexChoice < vInventory.size()) );
std::cout << "Enter new quantity: ";
getline( std::cin, usrInptQntyStr );
inSS.str( usrInptQntyStr );
inSS >> usrInptQnty;
inSS.clear();
vInventory.at(usrIndexChoice)->setQuantity(usrInptQnty);
}
} // updateItemQtyInInventory
// ----------------------------------------------------------------------------
// removeItemFromInventory()
// Here we will be removing an entire item from the inventory
void Inventory::removeItemFromInventory( std::vector<Inventory*>& vInventory) {
std::istringstream inSS;
std::string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
std::string usrInptQntyStr = "";
if ( vInventory.size() == 0 ) {
std::cout << "No items to remove." << std::endl;
} else {
printInventory( vInventory );
do {
std::cout << "Remove which item #: ";
getline( std::cin, usrIndexChoiceStr );
inSS.str( usrIndexChoiceStr );
inSS >> usrIndexChoice;
inSS.clear();
} while ( !(usrIndexChoice < vInventory.size()) );
vInventory.erase( vInventory.begin() + usrIndexChoice );
}
} // removeItemFromInventory
main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
//using namespace std; // Bad Practice To Use This In A Global Scope!
#include "Inventory.h"
// ----------------------------------------------------------------------------
// main()
int main() {
std::vector<Inventory*> vInventory;
std::string strUsrInptOptn = "default";
std::string strUsrInptOptn2 = "default";
Inventory update;
while (true) {
// Get user choice
std::cout << "\nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
getline( std::cin, strUsrInptOptn);
// Process user choice
if ( strUsrInptOptn.size() == 0 ) {
continue;
} else if ( strUsrInptOptn.at(0) == 'p' ) {
update.printInventory( vInventory ); //Different!
} else if ( strUsrInptOptn.at(0) == 'a' ) { ///I don't know what the difference is between the three slashes and the two, but they are different!
std::cout << "\nEnter (b)ook or (p)roduce: ";
getline( std::cin, strUsrInptOptn2 );
if ( strUsrInptOptn2.at(0) == 'b' ) {
update.addBookToInventory( vInventory ); //Supposed to look like: INV = AddItem...(INV);
} else if ( strUsrInptOptn2.at(0) == 'p' ) {
update.addProduceToInventory( vInventory );
} else {
continue;
}
} else if ( strUsrInptOptn.at(0) == 'u' ) {
update.updateItemQtyInInventory( vInventory );
} else if ( strUsrInptOptn.at(0) == 'r' ) {
update.removeItemFromInventory( vInventory );
} else if ( strUsrInptOptn.at(0) == 'q') {
std::cout << "\nGood bye." << std::endl;
break;
}
} // while
return 0;
} // main
With this the code is much cleaner looking with an elegant feel. The main.cpp isn't cluttered with tons of lines of code; it is always good practice to keep main.cpp short and simple since this is where the main executable starts. I created a class of your inventory and put it in its own module in a *.h and *.cpp file. I also separated its declaration from its definition or its implementation. This way if someone else is looking at your source code to use it; they do not have to know exactly how the function works, only what it is supposed to do. The interface or *.h file should tell you everything you need to know about the class object and how it is used. Also this allows for cleaner and quicker build times since you only have to compile this class's *.cpp file only when you changed something within instead of rebuilding the entire solution.
Now there are some instances where you might want to have the implementation in the header file and some cases where you don't have a choice and it has to be. The cases where you might want the implementation to be in the header file is if your methods are declared as inline or you are creating a header only library. The case where you may not have a choice but to have it in the header file is if you are creating class templates or function templates however when you have these two types either inline member functions, class template member functions or function templates these will usually be found in an inline file or an *.inl and you would include this file using the #include directive outside of your class's declaration and before the #endif header guard; if you are using #pragma once instead of the #ifndef #define #endif then you would just have this after the class's declaration.
Once you start to have a constant structure of your code that you prefer; it will become easier to debug and find errors.
Out side of your question I think I have noticed another bug that you have introduced that you may or may not be aware of; I think you may have a memory leak in your program!
I hope this serves as a guide to help you. If I get the chance within the next couple of days; I may go ahead and either try to debug your code or try to rewrite your program in a slightly more elegant way. If I do get around to it I'll post it as another answer.
I have written a version of the program that the user had requested. It took me a little bit of time to work out the bugs and to make sure that it is working as expected. This doesn't meant that it is completely bug free. If anyone happens to find any bugs please feel free to comment and list any bugs so that I can fix them and make the appropriate edits.
This program is written in C++ using Win32 Console Application compiled and built with VS 2015.
What I have done here is created a small class hierarchy. The StoreItem class is an abstract base class meaning you can not create an object of this type directly since its constructors are protected. Any class object that inherits from this base class can be constructed publicly. I did this since different product types may have different information about them.
I took what was common about all Product Types and stored that information into the base class using protected members and public access functions. The only private member in the base class is the Type the inherited class is upon construction. These are just objects that contain data and methods. The Inventory class is what does a majority of the work to store and remove items, to calculate totals and to print its list.
I designed it this way so that the StoreItem and its inherited classes do not have any dependences with the iostream objects. The Inventory class only uses the std::cout objects within its printing method.
The only section of code that works with the input or the std::cin object is within the main function in the working while loop.
Having a structure such as this, allows these classes to be modular, or reusable. This also makes it easy to add another type or store item. You would have to create another class that is derived from StoreItem, Add in the Enumerated type, then repeat the process of adding in the appropriate functions within the Inventory and within the user choice branching.
This could be simplified a little more but I tried to keep this as close to the user's original program. I did not elect to use generic template types which is also a very useful and an efficient way of implementing it to reduce the amount of code redundancy. One needs to master these basic concepts before they can begin to move onto more advanced topics.
stdafx.h
#ifndef STDAFX_H
#define STDAFX_H
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <string>
#include <iostream>
#include <memory>
//#include <sstream> // Not Using stringstring, istringstream, or ostringstream
#include <vector>
#endif // STDAFX_H
stdafx.cpp
#include "stdafx.h"
StoreItem.h
#ifndef STORE_ITEM_H
#define STORE_ITEM_H
class StoreItem {
public:
enum ItemType {
ITEM_BOOK = 0,
ITEM_PRODUCE,
}; // ItemType
protected:
std::string m_strItemName;
float m_priceInDollars;
private:
ItemType m_type;
public:
std::string getItemName() const;
float getItemPrice() const;
void setItemName( const std::string& strItemName );
void setItemPrice( float price );
ItemType getItemType() const;
protected:
explicit StoreItem( ItemType type );
StoreItem( ItemType type, const std::string& strItemName, float priceInDollars );
}; // StoreItem
#endif // STORE_ITEM_H
StoreItem.cpp
#include "stdafx.h"
#include "StoreItem.h"
// ----------------------------------------------------------------------------
// StoreItem()
StoreItem::StoreItem( ItemType type ) :
m_type( type ) {
} // StoreItem
// ----------------------------------------------------------------------------
// StoreItem()
StoreItem::StoreItem( ItemType type, const std::string& strItemName, float priceInDollars ) :
m_type( type ),
m_strItemName( strItemName ),
m_priceInDollars( priceInDollars ){
} // StoreItem
// ----------------------------------------------------------------------------
// getItemType()
StoreItem::ItemType StoreItem::getItemType() const {
return m_type;
} // getItemType
// ----------------------------------------------------------------------------
// setItemName()
void StoreItem::setItemName( const std::string& strItemName ) {
m_strItemName = strItemName;
} // setItemName
// ----------------------------------------------------------------------------
// getItemName()
std::string StoreItem::getItemName() const {
return m_strItemName;
} // getItemName
// ----------------------------------------------------------------------------
// setItemPrice()
void StoreItem::setItemPrice( float priceInDollars ) {
m_priceInDollars = priceInDollars;
} // setItemPrice
// ----------------------------------------------------------------------------
// getItemPrice()
float StoreItem::getItemPrice() const {
return m_priceInDollars;
} // getItemPrice
Book.h
#ifndef BOOK_H
#define BOOK_H
#include "StoreItem.h"
class Book sealed : public StoreItem {
private:
std::string m_strAuthorName;
public:
Book();
Book( const std::string& strItemName, float priceInDollars, const std::string& strAuthor );
void setAuthorName( const std::string& strAuthor );
std::string getAuthorName() const;
}; // Book
#endif // BOOK_H
Book.cpp
#include "stdafx.h"
#include "Book.h"
// ----------------------------------------------------------------------------
// Book()
Book::Book() :
StoreItem( ITEM_BOOK ) {
} // Book
// ----------------------------------------------------------------------------
// Book()
Book::Book( const std::string& strItemName, float priceInDollars, const std::string& strAuthorName ) :
StoreItem( ITEM_BOOK, strItemName, priceInDollars ),
m_strAuthorName( strAuthorName ) {
} // Book
// ----------------------------------------------------------------------------
// setAuthorName()
void Book::setAuthorName( const std::string& strAuthorName ) {
m_strAuthorName = strAuthorName;
} // setAuthorName
// ----------------------------------------------------------------------------
// getAuthorName()
std::string Book::getAuthorName() const {
return m_strAuthorName;
} // getAuthorName
Produce.h
#ifndef PRODUCE_H
#define PRODUCE_H
#include "StoreItem.h"
class Produce sealed : public StoreItem {
private:
std::string m_strExpirationDate;
public:
Produce();
Produce( const std::string& strItemName, float priceInDollars, const std::string& strExpirationDate );
void setExpirationDate( const std::string& strExpirationDate );
std::string getExpirationDate() const;
}; // Produce
#endif // PRODUCE_H
Produce.cpp
#include "stdafx.h"
#include "Produce.h"
// ----------------------------------------------------------------------------
// Produce()
Produce::Produce() :
StoreItem( ITEM_PRODUCE ) {
} // Produce
// ----------------------------------------------------------------------------
// Produce()
Produce::Produce( const std::string& strItemName, float priceInDollars, const std::string& strExpirationDate ) :
StoreItem( ITEM_PRODUCE, strItemName, priceInDollars ),
m_strExpirationDate( strExpirationDate ) {
} // Produce
// ----------------------------------------------------------------------------
// setExpirationDate()
void Produce::setExpirationDate( const std::string& strExpirationDate ) {
m_strExpirationDate = strExpirationDate;
} // setExpirationDate
// ----------------------------------------------------------------------------
// getExpirationDate()
std::string Produce::getExpirationDate() const {
return m_strExpirationDate;
} // getExpirationDate
Inventory.h
#ifndef INVENTORY_H
#define INVENTORY_H
#include "StoreItem.h" // Needed For StoreItem::ItemType
class Book;
class Produce;
class Inventory {
private:
typedef std::vector<std::shared_ptr<Book>> PtrBooks;
typedef std::vector<std::shared_ptr<Produce>> PtrProduce;
PtrBooks m_vBooks;
PtrProduce m_vProduce;
public:
void addBook( const std::string& strName, const std::string& strAuthor, float price );
void addProduce( const std::string& strName, const std::string& strExpiration, float price );
void removeItemFromIventory( StoreItem::ItemType type, const std::string& strItemName, unsigned idx );
void showInventory() const;
bool isBookListEmpty() const;
bool isProduceListEmpty() const;
}; // Inventory
Inventory.cpp
#include "stdafx.h"
#include "Inventory.h"
#include "Book.h"
#include "Produce.h"
// ----------------------------------------------------------------------------
// addBook()
void Inventory::addBook( const std::string& strName, const std::string& strAuthor, float price ) {
m_vBooks.push_back( std::shared_ptr<Book>( new Book( strName, price, strAuthor ) ) );
} // addItemTo
// addProduce()
void Inventory::addProduce( const std::string& strName, const std::string& strExpiration, float price ) {
m_vProduce.push_back( std::shared_ptr<Produce>( new Produce( strName, price, strExpiration ) ) );
} // addProduce
// ----------------------------------------------------------------------------
// removeItemFromInventory()
void Inventory::removeItemFromIventory( StoreItem::ItemType type, const std::string& strItemName, unsigned idx ) {
if ( strItemName.empty() ) {
// throw Exeption Here
return;
}
unsigned counter = 1; // User Based, Not Vector or Array Based
if ( type == StoreItem::ITEM_BOOK ) {
PtrBooks::iterator it = m_vBooks.begin();
for ( ; it != m_vBooks.end(); ++it ) {
if ( it->get()->getItemName() == strItemName && counter == idx ) {
// Found It
it->reset();
m_vBooks.erase( it );
return;
}
counter++;
}
}
// Reset Counter
counter = 1;
if ( type == StoreItem::ITEM_PRODUCE ) {
PtrProduce::iterator it = m_vProduce.begin();
for ( ; it != m_vProduce.end(); ++it ) {
if ( it->get()->getItemName() == strItemName && counter == idx ) {
// Found It
it->reset();
m_vProduce.erase( it );
return;
}
counter++;
}
}
} // removeItemFromInventory()
// ----------------------------------------------------------------------------
// showInventory()
void Inventory::showInventory() const {
float totalCostBooks = 0;
float totalCostProduce = 0;
std::flush( std::cout );
std::cout << "\n-------------" << std::endl
<< "Sales Invoice" << std::endl
<< "-------------" << std::endl << std::endl;
std::cout << "Book Information: " << std::endl;
for ( unsigned u = 0; u < m_vBooks.size(); ++u ) {
std::cout << u + 1 << ": "
<< m_vBooks.at( u ).get()->getItemName() << " "
<< m_vBooks.at( u ).get()->getAuthorName() << " "
<< "$" << m_vBooks.at( u ).get()->getItemPrice() << std::endl;
totalCostBooks += m_vBooks.at( u ).get()->getItemPrice();
}
std::cout << "Total Cost Of Books: $" << totalCostBooks << std::endl << std::endl;
std::cout << "Produce Information: " << std::endl;
for ( unsigned u = 0; u < m_vProduce.size(); ++u ) {
std::cout << u + 1 << ": "
<< m_vProduce.at( u ).get()->getItemName() << " "
<< m_vProduce.at( u ).get()->getExpirationDate() << " "
<< "$" << m_vProduce.at( u ).get()->getItemPrice() << std::endl;
totalCostProduce += m_vProduce.at( u ).get()->getItemPrice();
}
std::cout << "Total Cost Of Produce: $" << totalCostProduce << std::endl << std::endl;
std::cout << "------------------" << std::endl
<< "Grand Total: $" << totalCostBooks + totalCostProduce << std::endl;
} // showInventory
// ----------------------------------------------------------------------------
// isBookListEmpty()
bool Inventory::isBookListEmpty() const {
return m_vBooks.empty();
} // isBookListEmpty
// ----------------------------------------------------------------------------
// isProduceListEmpty()
bool Inventory::isProduceListEmpty() const {
return m_vProduce.empty();
} // isProduceListEmpty
main.cpp
// StoreInventory.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "Inventory.h"
int main() {
Inventory inventory;
std::string userInput;
bool quit = false;
while ( !quit ) {
std::cout << "\nEnter (a)dd, (r)emove, (s)how inventory, (q)uit: ";
std::cin >> userInput;
if ( userInput[0] == 'a' || userInput[0] == 'A' ) {
std::cout << "\nEnter (b)ook or (p)roduce: ";
std::cin >> userInput;
if ( userInput[0] == 'b' || userInput[0] == 'B' ) {
std::string strName;
std::string strAuthor;
float price = 0;
std::cout << "\nEnter the name of the book. ";
std::getline( std::cin, strName ); // For Some Reason I have To Add This Twice
std::getline( std::cin, strName );
std::cout << "\nEnter the book's author. ";
std::getline( std::cin, strAuthor );
std::cout << "\nEnter the price in US Dollars. ";
std::cin >> price;
inventory.addBook( strName, strAuthor, price );
} else if ( userInput[0] == 'p' || userInput[0] == 'P' ) {
std::string strName;
std::string strExpiration;
float price = 0;
std::cout << "\nEnter the type of produce. ";
std::getline( std::cin, strName ); // For Some Reason I have To Add This Twice
std::getline( std::cin, strName );
std::cout << "\nEnter the expiration date. ";
std::getline( std::cin, strExpiration );
std::cout << "\nEnter the price in US Dollars. ";
std::cin >> price;
inventory.addProduce( strName, strExpiration, price );
} else {
std::cout << "\nInvalid Entry\n";
}
system( "cls" ); // If on windows and using win32 console
continue;
} else if ( userInput[0] == 'r' || userInput[0] == 'R' ) {
// Clear The Screen, Show The Inventory Then Ask User Which Item To Remove
system( "cls" ); // If on windows and using win32 console
inventory.showInventory();
std::cout << "\nWhich item would you like to remove (b)ook or (p)roduce? ";
std::cin >> userInput;
StoreItem::ItemType type;
if ( userInput[0] == 'b' || userInput[0] == 'B' ) {
if ( inventory.isBookListEmpty() ) {
std::cout << "\nThere are no entries availabe to remove. ";
continue;
} else {
type = StoreItem::ITEM_BOOK;
}
} else if ( userInput[0] == 'p' || userInput[0] == 'P' ) {
if ( inventory.isProduceListEmpty() ) {
std::cout << "\nThere are no entries available to remove. ";
continue;
} else {
type = StoreItem::ITEM_PRODUCE;
}
} else {
std::cout << "\nInvalid Type\n";
}
std::string strName;
unsigned idx;
std::cout << "\nEnter name of product you wish to remove. ";
std::getline( std::cin, strName ); // For Some Reason I have To Add This Twice
std::getline( std::cin, strName );
std::cout << "\nEnter item number of this type you wish to remove. ";
std::cin >> idx;
inventory.removeItemFromIventory( type, strName, idx );
continue;
} else if ( userInput[0] == 's' || userInput[0] == 'S' ) {
system( "cls" ); // If on windows and using win32 console
inventory.showInventory();
continue;
} else if ( userInput[0] == 'q' || userInput[0] == 'Q' ) {
quit = true;
break;
} else {
std::cout << "\nInvalid Entry\n";
continue;
}
} // while
std::cout << "\nPress any key to quit" << std::endl;
_getch();
return 0;
} // main
Few issues:
1.) priceInDollars was not being initialized properly
2.) totalInvPriceInDollars needs to be static
below code fixes the issues:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int totalInvPriceInDollars = 0 ;
class Inventory {
public:
Inventory(): priceInDollars(0) {};
void SetSumInv(int prcInDllrs, int individualquantity) {
priceInDollars = priceInDollars + (prcInDllrs * individualquantity);
totalInvPriceInDollars = totalInvPriceInDollars + priceInDollars;
}
void SetItemPrice(int whatever) {
itemsPrice = whatever;
}
void SetName(string nm)
{
name = nm;
};
void SetQuantity(int qnty)
{
quantity = qnty;
};
void SetAuthor(string athr) {
author = athr;
}
void SetExpiration(string expir)
{
expiration = expir;
};
virtual void Print(){
cout << name << " x" << quantity << " for: $" << itemsPrice; //" (Expires: " << expiration << ")";
if (expiration.size() != 0) {
cout << " (Expires: " << expiration << ")" << endl;
}
else {
cout << " (Author: " << author << ")" << endl;
}
}
void PrintInventory(vector<Inventory*> inventory) {
unsigned int i = 0;
if (inventory.size() == 0) {
cout << "No items to print." << endl;
}
else {
for (i = 0; i<inventory.size(); ++i) {
cout << i << " - ";
inventory.at(i)->Print();
}
cout << "Total inventory value: " << totalInvPriceInDollars;
}
return;
}
void AddItemToInventory()
{
}
vector<Inventory*> AddProduceToInventory(vector<Inventory*> inventory)
{
Inventory* prdc;
string usrInptName = "";
string usrInptQntyStr = "";
istringstream inSS;
istringstream inDD;
int usrInptQnty = 0;
string usrInptExpr = "";
string usrInptPrcStr = "";
int usrInptPrc = 0;
int ItemCost = 0;
cout << "Enter name of new produce: ";
getline(cin, usrInptName);
SetName(usrInptName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
SetQuantity(usrInptQnty);
cout << "Enter expiration date: ";
getline(cin, usrInptExpr);
SetExpiration(usrInptExpr);
cout << "Enter the price per item: $";
getline(cin, usrInptPrcStr);
inDD.str(usrInptPrcStr);
inDD >> usrInptPrc;
inDD.clear();
SetItemPrice(usrInptPrc);
ItemCost = (usrInptPrc * usrInptQnty);
prdc = new Inventory;
prdc->SetName(usrInptName);
prdc->SetQuantity(usrInptQnty);
prdc->SetExpiration(usrInptExpr);
prdc->SetSumInv(usrInptPrc, usrInptQnty);
prdc->SetItemPrice(usrInptPrc);
inventory.push_back(prdc);
return inventory;
}
void AddBookToInventory()
{
}
vector<Inventory*> AddBookToInventory(vector<Inventory*> inventory) {
Inventory* prdct;
string usrInptName = "";
string usrInptQntyStr = "";
istringstream inSS;
int usrInptQnty = 0;
string usrInptAthr = "";
string usrInptPrcStr = "";
int usrInptPrc = 0;
istringstream inDD;
int sum = 0;
int ItemCost = 0;
cout << "Enter name of new book: ";
getline(cin, usrInptName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
cout << "Enter author: ";
getline(cin, usrInptAthr);
cout << "Enter the price per item: $";
getline(cin, usrInptPrcStr);
inDD.str(usrInptPrcStr);
inDD >> usrInptPrc;
inDD.clear();
ItemCost = (usrInptPrc * usrInptQnty);
prdct = new Inventory;
prdct->SetName(usrInptName);
prdct->SetQuantity(usrInptQnty);
prdct->SetSumInv(usrInptPrc, usrInptQnty);
prdct->SetAuthor(usrInptAthr);
prdct->SetItemPrice(usrInptPrc);
inventory.push_back(prdct);
return inventory;
}
void UpdateItemQtyInventory()
{}
//This is the update function in which we can change how many items a certain purchase has
vector<Inventory*> UpdateItemQtyInInventory(vector<Inventory*> inventory) {
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
istringstream inSS;
string usrInptQntyStr = "";
int usrInptQnty = 0;
if (inventory.size() == 0) {
cout << "No items to update." << endl;
}
else {
PrintInventory(inventory);
do {
cout << "Update which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
cout << "Enter new quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
inventory.at(usrIndexChoice)->SetQuantity(usrInptQnty);
}
return inventory;
}
void RemoveItemFromInventory()
{}
//Here we will be removing an entire item from the inventory
vector<Inventory*> RemoveItemFromInventory(vector<Inventory*> inventory) {
istringstream inSS;
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
string usrInptQntyStr = "";
if (inventory.size() == 0) {
cout << "No items to remove." << endl;
}
else {
PrintInventory(inventory);
do {
cout << "Remove which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
inventory.erase(inventory.begin() + usrIndexChoice);
}
return inventory;
}
void GetTotalValueAsPrice()
{
}
protected:
string name;
int quantity;
int priceInDollars ;
int totalCost;
int itemsPrice;
string expiration;
string author;
};
int main() {
vector<Inventory*> INVENTORY;
string usrInptOptn = "default";
string usrInptOptn2 = "default";
Inventory update;
while (true) {
// Get user choice
cout << "\nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
getline(cin, usrInptOptn);
// Process user choice
if (usrInptOptn.size() == 0) {
continue;
}
else if (usrInptOptn.at(0) == 'p') {
update.PrintInventory(INVENTORY); //Different!
}
else if (usrInptOptn.at(0) == 'a') {///I don't know what the difference is between the three slashes and the two, but they are different!
cout << "\nEnter (b)ook or (p)roduce: ";
getline(cin, usrInptOptn2);
if (usrInptOptn2.at(0) == 'b') {
INVENTORY = update.AddBookToInventory(INVENTORY); //Supposed to look like: INV = AddItem...(INV);
}
else if (usrInptOptn2.at(0) == 'p') {
INVENTORY = update.AddProduceToInventory(INVENTORY);
}
else
{
continue;
}
}
else if (usrInptOptn.at(0) == 'u') {
INVENTORY = update.UpdateItemQtyInInventory(INVENTORY);
}
else if (usrInptOptn.at(0) == 'r') {
INVENTORY = update.RemoveItemFromInventory(INVENTORY);
}
else if (usrInptOptn.at(0) == 'q') {
cout << "\nGood bye." << endl;
break;
}
}
return 0;
}

C++ Search for a unique word and assign it a number

I am looking at various examples of reading an input file and counting the occurrences of a word. Then give it a variable to count.
Lets say we have an input file and you want to look for how many times the word "account" or word "like" shows up and give it the variable "1.2". So when you find the word, count how many times it occurs and then times it by 1.2 .
How would you go about doing this?
EDIT: This is the only way I know how. However, this pre-searches the word versus letting the user search it
#include <iostream>
#include <fstream>
using namespace std;
int main(void)
{
int option=0; //option number
ifstream inputFile;
string filename;
cout << "Welcome\n" << endl;
//Getting the input file
cout << "Enter input data file name:";
cin >> filename;
cout << endl;
fin.open(filename.c_str()); // change to C-string
if (!inputFile) {// makes sure file exist
cout << "Unable to open " << filename << endl;
cin.get();
return 1;
}
do {
cout << "5- Count frequency of the following three words individually: I, like, is" << endl;
cout << "6 - To quit";
cout << endl;
cin >> option;
int iWord = 0;
int likeWord = 0;
int isWord = 0;
if (option == 5) {
string word;
do {
inputFile >> word;
if (word == "I") iWord++;
else if (word== "like") likeWord++;
else if (word == "is") isWord++;
}while (inputFile.good());
cout << "The word I is repeated " << iWord << " times" << endl;
cout << "The word is has been repeated " << isWord << " times" << endl;
cout << "The word like is repeated " << likeWord << " times" << endl << endl;
}
inputFile.clear(); // clear fail bit or seekg won't work!
inputFile.seekg (0, ios::beg);
}while (option != 6);
return 0;
}
Not the most efficient way (especially for one word), but maybe this could give you direction:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <unordered_map>
void tokenize( const std::string & line, std::unordered_map< std::string, size_t > & map_count )
{
for( std::string::size_type pos_start = 0, pos_end = 0; ( pos_end != std::string::npos ) && ( pos_start = line.find_first_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", pos_end ) ) != std::string::npos; )
{
pos_end = line.find_first_not_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", pos_start );
std::string current_word = ( pos_end == std::string::npos ) ? line.substr( pos_start ) : line.substr( pos_start, pos_end - pos_start );
std::unordered_map< std::string, size_t >::iterator iter( map_count.find( current_word ) );
if( iter == map_count.end() )
map_count.insert( std::pair< std::string, size_t >( current_word, 1 ) );
else
++( iter->second );
}
}
void countWordsInFile( const std::string & filename, std::unordered_map< std::string, size_t > & map_count )
{
std::ifstream in( filename );
std::string line;
size_t count = 0;
if( in.is_open() )
while( std::getline( in, line ).good() )
tokenize( line, map_count );
}
double countAndWeigh( const std::string & filename, const std::string & word, double weight )
{
std::unordered_map< std::string, size_t > map_count;
countWordsInFile( filename, map_count );
std::unordered_map< std::string, size_t >::const_iterator iter( map_count.find( word ) );
return ( iter != map_count.end() ) ? iter->second * weight : 0;
}
int main( int argc, char ** argv )
{
if( argc == 4 )
std::cout << countAndWeigh( argv[1], argv[2], strtod( argv[3], nullptr ) ) << std::endl;
return 0;
}

Recursion of an index

Hello fellow programmers, I have a question about recursion that I do not understand, being new to C++ and all. So for this exercise I am completing, I need to: 1. Ask user for a string 2. Ask user for a string to search in the first string entered. 3. report and index of the string if it finds it. For instance the user enters the string "Search me", string to search for is "me", and the index would return "7". I am throwing my hands up at this point for some help on how to complete it, any help would be appreciated. Here is my code thus far. The stuff that is in the for loop isn't a complete thought, just FYI.
int index_of(string stringToSearchIn, string stringToSearchFor, int index)
{
if (stringToSearchIn.length() < stringToSearchFor.length())
{
cout << "Your string cannot be found." << endl;
system("PAUSE");
return OUTLIER;
}
else
{
bool found = true;
for (int i = ZERO; i < stringToSearchFor.length; i++)
{
found = found && stringToSearchIn(i) == stringToSearchFor(i);
}
return index;
}
return index_of(stringToSearchIn.substr(INCREASE), stringToSearchFor, index++);
}
int main()
{
//Initializing values
string userString;
string userSearch;
int userIndex = 0;
//Asking for user input for string
cout << "This program will find the occurence of one string inside of another." << endl;
cout << "Enter the string to be searched: " << userString;
//Getting the string
getline(cin, userString);
//Asking for user input for search input
cout << "Now enter the string you want to search for: " << userSearch;
//Getting the string
getline(cin, userSearch);
//Displaying results
cout << "The index of the substring is = " << index_of(userString, userSearch, userIndex);
//Keeping console window open until key press
system("PAUSE");
return ZERO;
}
Catch.:)
#include <iostream>
size_t index_of( const char *s, const char *t )
{
const char *p = s;
const char *q = t;
while ( *q && *p == *q ) ++p, ++q;
if ( *q == '\0' )
{
return 0;
}
else if ( *p == '\0' )
{
return -1;
}
else
{
size_t n = 1 + index_of( s + 1, t );
return n == 0 ? -1 : n;
}
}
int main()
{
const char *s = "Search me";
const char *t = "me";
size_t n = index_of( s, t );
if ( n != -1 )
{
std::cout << "string " << t << " is found at position " << n << std::endl;
}
else
{
std::cout << "string " << t << " is not found" << std::endl;
}
return 0;
}
The output is
string me is found at position 7
For other strings I did not test the function.:)
For objects of type std::string you can call it like
size_t n = index_of( s.c_str(), t.c_str() );
Otherwise if you want to write a similar recursive function for objects of type std::string then you need either to add a static local variable that to keep the current position inside the source string or add one more parameter for index or use member function substr.
Also my advice is do not use manifest constant ZERO for zero. In my opinion it is a bad style of programming. It only confuses readers because ZERO can be anything including some user-defined class.
For example (without testing)
#include <iostream>
#include <string>
std::string::size_type index_of( const std::string &s, const std::string &t )
{
static std::string::size_type pos;
if ( s.size() < t.size() ) return std::string::npos;
if ( s.compare( pos, t.size(), t ) == 0 ) return 0;
++pos;
std::string::size_type n = index_of( s, t );
--pos;
return n == std::string::npos ? std::string::npos : n + 1;
}
int main()
{
std::string s = "Search me";
std::string t = "me";
std::string::size_type n = index_of( s, t );
if ( n != std::string::npos )
{
std::cout << "string " << t << " is found at position " << n << std::endl;
}
else
{
std::cout << "string " << t << " is not found" << std::endl;
}
return 0;
}
As for your function realization then it can look for example the following way
#include <iostream>
#include <string>
std::string::size_type index_of( const std::string &stringToSearchIn,
const std::string &stringToSearchFor,
std::string::size_type index )
{
if ( stringToSearchIn.length() < stringToSearchFor.length() + index )
{
return std::string::npos;
}
else if ( stringToSearchIn.compare( index,
stringToSearchFor.length(),
stringToSearchFor ) == 0 )
{
return index;
}
else
{
std::string::size_type n =
index_of( stringToSearchIn, stringToSearchFor, ++index );
return n == std::string::npos ? std::string::npos : n;
}
}
int main()
{
std::string s = "Search me";
std::string t = "me";
std::string::size_type n = index_of( s, t, 0 );
if ( n != std::string::npos )
{
std::cout << "string " << t << " is found at position " << n << std::endl;
}
else
{
std::cout << "string " << t << " is not found" << std::endl;
}
return 0;
}

std::out of range in a noxim code

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