//////////////////////////////////////////////////////////////////
// Capture a lambda with a lambda and use it in the lambda it's //
// captured in along with some code in the lambda that captures //
// it. //
// //
// Add to that to capture a variable in the client and use that //
// too. //
// //
// Then make a lambda that captures a class object and calls //
// some method or methods with it, optionally modifies the re- //
// sult... //
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// Note: std::function<type(type)> f; //
// f = <define lambda here> //
// f() //calls lambda //
//////////////////////////////////////////////////////////////////
#include <functional>
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::function;
using std::getline;
using std::string;
class Experimental {
private:
int x;
string s;
public:
Experimental() {}
~Experimental() {}
void set_x(int new_x);
int get_x();
void set_s(string s_in);
string get_s();
};
void Experimental::set_x(int new_x) {
x = new_x;
}
int Experimental::get_x() {
return (x);
}
void Experimental::set_s(string s_in) {
s = s_in;
}
string Experimental::get_s() {
return s;
}
int main() {
double n;
string input;
Experimental* experiment = new Experimental();
cout << "Enter a number: ";
cin >> n;
function<double(double)> f;
f = [&f](double k) {
return (k ? k * f(k-1) : 1);
};
function<double(double)> g;
g = [&f,n](double m) {
return (f(n)/n);
};
function<int()> T1; //capture a class and do stuff...
T1 = [&experiment,n]() {
experiment->set_x(13 + n);
int m = experiment->get_x();
return (m);
};
function<string(string)> T2; //capture a class and do stuff...
T2 = [&experiment](const string in) {
experiment->set_s(in);
string s = experiment->get_s();
return (s);
};
cout << "The factorial of " << n << " is: ";
cout << f(n) << endl;
cout << "The factorial of " << n << " divided by " << n << " is: ";
cout << g(n) << endl;
cout << "The new value of x in experiment is: ";
cout << T1() << endl;
cout << "Enter a string: ";
getline(cin, input); //FIXME
cout << "input is: " << input << "<-" << endl;
cout << "The new string in experiment is: ";
cout << T2(input) << endl;
delete experiment;
return (0);
}
I know it's ugly. Not reeally using lambdas as they're meant to be used while I experiment here at first. For some reason I'm not getting input for my string variable and I don't know why. Can someone help/ point out what the problem is?
The problem is your getline is reading the end-of-line left in the buffer after:
cin >> n;
Fix that by using ignore:
#include <limits>
...
cin >> n;
...
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
getline(cin, input);
This is a very common error, basically you have
cin >> number;
getline(cin, str);
Now think about this (you seem a good programmer so I'm only giving you a clue). How many newlines are contained in a number? How many newlines will cin >> number; actually read?
Related
I'm trying to use a loop to infinitely create objects from a class unless a specific input is entered. I think I have everything done except the loop. I know how to initialize one object in my main function, but I'm stuck as to how to use a loop to do this infinitely. My code is below.
Driver File:
#include <iostream>
#include "square.h"
using namespace std;
int main()
{
square square1;
square1.setSide();
square1.calcArea();
square1.calcPerimeter();
square1.showData();
}
Header file:
#pragma once
#include <string>
class square
{
public:
square();
void setSide();
double getSide() const;
void calcPerimeter();
void calcArea();
void showData();
private:
double squareSide;
double squarePerimeter;
double squareArea;
};
Implementation file:
#include <iostream>
#include <iomanip>
#include "square.h"
square::square()
{
squareSide = 0;
squarePerimeter = 0;
squareArea = 0;
}
void square::setSide()
{
std::cout << "Enter a side length: ";
std::cin >> squareSide;
std::cout << "\n";
if (squareSide == -1)
{
std::cout << "Exiting program.\n";
exit(-1);
}
while (std::cin.fail() || squareSide < 0)
{
std::cout << "\nYou must enter a positive number. Please try again.\n\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Enter a side length: ";
std::cin >> squareSide;
}
}
double square::getSide() const
{
return squareSide;
}
void square::calcPerimeter()
{
squarePerimeter = 4 * getSide();
}
void square::calcArea()
{
squareArea = getSide() * getSide();
}
void square::showData()
{
std::cout << "The side length of the square is: " << getSide() << "\n";
std::cout << "The perimeter of the square is: " << getSide() * 4 << "\n";
std::cout << "The area of the square is: " << getSide() * getSide() << "\n";
}
You could add a do ... while loop around your code in main and store the squares in a vector<square>.
Example:
#include <limits> // you use numeric_limits from this header
#include <utility> // move
#include <vector> // vector
int main() {
std::vector<square> squares;
std::string answer;
do {
square square1;
square1.setSide();
square1.calcArea();
square1.calcPerimeter();
// move the square into the vector
squares.push_back(std::move(square1));
// ask the user if he/she wants to enter another
std::cout << "Go again? ";
} while(std::cin >> answer && answer == "yes");
// display what you stored
std::cout << "You stored " << squares.size() << " square(s)\n";
for(square& sq : squares) {
sq.showData();
std::cout << '\n';
}
}
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
class Profesor
{
public:
string nume, departament;
int grad, vechime;
Profesor(string n, string d, int g, int v);
};
Profesor::Profesor(string n, string d, int g, int v) {
nume = n;
departament = d;
grad = g;
vechime = v;
}
int main()
{
list <Profesor*> profi;
Profesor* p;
int opt;
string nume, departament;
int grad, vechime;
do {
cout << "1.Adaugare" << endl;
cout << "Dati optiunea! " << endl;
cin >> opt;
switch (opt)
{
case 1:
cout << "Nume:";
cin >> nume;
cout << "Departament:";
cin >> departament;
cout << "Grad:";
cin >> grad;
cout << "Vechime";
cin >> vechime;
p = new Profesor(nume, departament, grad, vechime);
profi.push_front(p);
default:
break;
}
} while (opt);
return 0;
}
Option 1 is to add a new item into the list
This is the constructor of the class
So I need a function to display the entire list
ajgnsjdgn afkajkf nskjfnakfakfnaf afnakfnasdnlang akfnafdakfrnaasf asdfkasfna
ad akjdgnakjsgsa askfnaksd asgnaskdng asdgjnsadgag
Add a function to Profesor to output it's current variables:
void output() const {
cout << " * nume: " << nume << endl;
cout << " * departament: " << departament << endl;
cout << " * grad: " << grad << endl;
cout << " * vechime: " << vechime << endl;
}
Create a function that iterates through the list and calls this function.
Here is an example that uses a range based for loop:
void outputProfesors(const list<Profesor*>& profesors) {
for (const auto& profesor : profesors) {
profesor->output();
}
}
Call outputProfesors().
I want to create a program which is able to calculate the surface area, volume, and circumference. for your additional info, I am studying about function, I has just learned about C++ about a week.
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int getPostP(string msgP)
{
int Ppost= 0.000;
do
{
cout << msgP << endl;
cin >> Ppost;
return Ppost;
} while(Ppost<= 0);
}
int getPostL(string msgL)
{
int Lpost= 0.000;
do
{
cout << msgL << endl;
cin >> Lpost;
return Lpost;
} while(Lpost<= 0);
}
int getPostT(string msgT)
{
int Tpost = 0.000;
do
{
cout << msgT << endl;
cin >> Tpost;
return Tpost;
} while(Tpost <= 0);
}
int surfaceArea(int Psur, int Lsur, int Tsur)
{
return (2*Psur*Lsur)+(2*Psur*Tsur)+(2*Lsur*Tsur);
}
int volume(int Pvol, int Lvol, int Tvol)
{
return (Pvol*Lvol*Tvol);
}
float circumference(int Pcir, int Lcir, int Tcir)
{
return 4*(Pcir+Lcir+Tcir);
}
int main()
{
int P = getPostP("enter the P of your block");
int L = getPostL("enter the L of your block");
int T = getPostT("enter the T of your block");
float surfAreaBlock = surfaceArea(P, L, T);
float volBlock = volume(P, L, T);
float cirBlock = circumference(P, L, T);
cout << "block which have P = " << P << " and L = " << L << " and T = "<< T << " have surface area = " <<
surfAreaBlock << " and volume = " << volBlock << " and cirBlock = " << cirBlock;
return 0;
}
Maybe one of you want to rewrite and add some comment, which parts are able to simplify, so I can understand easier.
First of all, it looks like you should make all of your integer inputs into double instead of int, since it's expected that your inputs won't necessarily be an exact integer amount (probably). Also you can get rid of all of your duplicate functions for entering the parameters. Change it to a single function and call that one for each variable.
double getInput(const std::string& prompt)
{
double input(0.0);
do
{
std::cout << prompt << "\n-> " << std::flush;
// forces input to be a double type
while (!(std::cin >> input))
{
std::cout << "\n-> " << std::flush;
std::cin.clear();
std::cin.ignore(256, '\n'); ///< could use streamsize::max here
}
} while (input <= 0.0); ///< make sure it's positive
return input;
}
I am the new kid in the block, studying C++. I have loaded a file stream in a list container, using variables. I want to be able to access and change the value of any of those variables. I've been trying for weeks to no avail. Can somebody help?
This is the external text file: flightBoard1.txt
Delta 3431 Paris JFK
Usair 2275 EWR London
Delta 1500 Bonn Milan
This is the main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <list>
using namespace std;
template<class T, class U, class V>
void changeFlight(list<string> &myFlight, T loc, U value, V newVal);
int main()
{
string _company;
int _flight;
string _origin;
string _destination;
list<string> flightBoard;
stringstream *ssPtr;
int counter = 0;
ifstream myFile("flightBoard1.txt");
while(myFile >> _company >> _flight >> _origin >> _destination ){
++counter;
ssPtr = new stringstream; // you want to put each line in a different slot in the flightBoard list object
*ssPtr << counter << " " << _company << "\t" << _flight << "\t" << _origin << "\t" << _destination << endl;
flightBoard.push_back(ssPtr->str()); // You need an arrow, this is a pointer
}
list<string>::iterator it;
for(it = flightBoard.begin(); it != flightBoard.end(); it++){
cout << *it ;
}
int oldFlight, newFlight;
cout << endl << "Enter old flight number: ";
cin >> oldFlight;
cout << "Enter new flight number: ";
cin >> newFlight;
changeFlight(flightBoard, ssPtr, oldFlight, newFlight);
delete ssPtr;
myFile.close();
return 0;
}
template<class T, class U, class V>
void changeFlight(list<string> &myFlight, T loc, U value, V newVal){
list<string>::iterator it;
cout << endl << "Flight: " << value << " has been changed to: " << newVal << endl;
for(it = myFlight.begin(); it != myFlight.end(); it++){
// THIS IS WHERE I AM HAVING A PROBLEM
// PLEASE UN-COMMENT BELOW TO SEE PROBLEM
/*if(it -> myFlight -> loc -> value){
value = newVal;
}*/
}
}
To solve your problem I think you should use the better structure for storage of your flights. string is not a good type if you need to manipulate data further. I suggest to introduce class Flight:
class Flight
{
public:
string company;
int flight;
string origin;
string destination;
Flight(const string& _company, int _flight, const string& _origin, const string& _destination)
: company(_company), flight(_flight), origin(_origin), destination(_destination)
{
}
string ToString() const
{
stringstream printer;
printer << company << "\t" << flight << "\t" << origin << "\t" << destination << endl;
return printer.str();
}
};
Also there are a number of problems in code snippet you have posted.
Memory leak inside while loop. You are allocating ssPtr = new stringstream; on each iteration, but delete it only once at the end.
changeFlight has too much template type arguments. If U value should be changed to V newVal inside changeFlight probably it should have the same types.
Hard to change type of flightBoard, list<string> copied everywhere. It's better to create typedef for list<string> type to make your code simpler. E.g. typedef list<string> FlightListType;.
Here is your code with all the mentioned problems fixed:
typedef list<Flight> FlightListType;
template<class T>
void changeFlight(FlightListType& myFlight, T value, T newVal);
int main()
{
string _company;
int _flight;
string _origin;
string _destination;
FlightListType flightBoard;
ifstream myFile("flightBoard1.txt");
while(myFile >> _company >> _flight >> _origin >> _destination )
{
flightBoard.push_back(Flight(_company, _flight, _origin, _destination));
}
FlightListType::const_iterator it;
int counter = 0;
for(it = flightBoard.begin(); it != flightBoard.end(); it++)
{
cout << counter << " " << (*it).ToString();
++counter;
}
int oldFlight, newFlight;
cout << endl << "Enter old flight number: ";
cin >> oldFlight;
cout << "Enter new flight number: ";
cin >> newFlight;
changeFlight(flightBoard, oldFlight, newFlight);
myFile.close();
return 0;
}
template<class T>
void changeFlight(FlightListType& myFlight, T value, T newVal)
{
FlightListType::iterator it;
cout << endl << "Flight: " << value << " has been changed to: " << newVal << endl;
for(it = myFlight.begin(); it != myFlight.end(); it++)
{
if ((*it).flight == value)
{
// TODO: Here you can do with the Flight what ever you need
// For example change it's number
(*it).flight = newVal;
}
}
}
How to get program read every line from .txt file and store 3 variables per line in different place ? I don't understand how can I store different value in same class. One line works fine but what I have tried more doesn't work.
class Team
{
public:
string name;
string dificulty;
string section;
};
void GetTeamInfo(Team& ko);
int main()
{
Team ko;
GetTeamInfo(ko);
cout << ko.name << " ";
cout << ko.dificulty<< " ";
cout << ko.section<< " ";
system("PAUSE");
}
void GetTeamInfo(Team& ko, int & i)
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open())
{
for(int i = 0; i < 10 ; i ++)
{
fd >> ko.name;
fd >> ko.dificulty;
fd >> ko.section ;
}
}
else
{
std::cout << "Mistake can't open file 'Team.txt'\n";
}
}
Try this:
void GetTeamInfo(vector<Team>& kos)
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open())
{
while (!d.eof())
{
Team ko;
fd >> ko.name;
fd >> ko.dificulty;
fd >> ko.section;
kos.push_back(ko);
}
}
...
}
I suggest you use a std::vector, since you have a number of teams.
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
class Team
{
public:
string name;
string dificulty;
string section;
};
void GetTeamInfo(vector<Team>& ko_v);
int main()
{
vector<Team> ko; // a vector of Teams
GetTeamInfo(ko); // read from file inside a vector
// print every team
for(unsigned int i = 0; i < ko.size(); ++i) {
cout << ko[i].name << " ";
cout << ko[i].dificulty<< " ";
cout << ko[i].section<< " ";
cout << "\n";
}
//system("PAUSE"); // don't use system()
return 0; // return 0 should be placed at the end of main
}
void GetTeamInfo(vector<Team>& ko_v) // you had an extra parameter here, no need to
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open()) // check if file is open
{
while (!fd.eof()) // while you have more to read
{
Team ko; // create a Team
fd >> ko.name; // read data
fd >> ko.dificulty;
fd >> ko.section;
ko_v.push_back(ko); // store that Team in the vector of teams
}
}
else
{
cout << "File not opened!\n";
}
}
Why not to use an array? You could use an array of course, but since this is C++, std::vector's usage is encouraged. Moreover, you don't have to worry about the number of the Teams you are going to read from the file. If you would have used an array, you should know apriori the number of the Teams, or dynamically allocate memory.
Why not use system(pause); ?
Just for a glance, I am modifying the example with the use of an array.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Team
{
public:
string name;
string dificulty;
string section;
};
void GetTeamInfo(Team* ko_ar, const int N);
int main()
{
const int N = 3; // number of teams in the file
Team ko[N]; // a vector of Teams
GetTeamInfo(ko, N); // read from file inside a vector
// print every team
for(int i = 0; i < N; ++i) {
cout << ko[i].name << " ";
cout << ko[i].dificulty<< " ";
cout << ko[i].section<< " ";
cout << "\n";
}
//system("PAUSE"); // don't use system()
return 0; // return 0 should be placed at the end of main
}
void GetTeamInfo(Team* ko_ar, const int N)
{
ifstream fd;
fd.open("Team.txt");
int i = 0;
if (fd.is_open()) // check if file is open
{
while (!fd.eof()) // while you have more to read
{
Team ko; // create a Team
fd >> ko.name; // read data
fd >> ko.dificulty;
fd >> ko.section;
if(i == N) {
cout << "Read more than " << N << " teams\n";
break;
}
ko_ar[i++] = ko; // store that Team in the vector of teams
}
}
else
{
cout << "File not opened!\n";
}
cout << "Read " << i << " teams\n";
}
Use a vector, here you have a full example(commented):
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Team
{
public:
// Adding a constructor.
Team(string name, string dificulty, string section):
name(name),
dificulty(dificulty),
section(section)
{}
string name;
string dificulty;
string section;
};
// Defining a convenience type;
typedef vector<Team> team_list_t;
// This function now receives a vector of teams.
void GetTeamInfo(team_list_t &tl);
int main()
{
team_list_t tl;
GetTeamInfo(tl);
for (vector<Team>::iterator it = tl.begin(); it != tl.end(); ++it)
cout << it->name << " " << it->dificulty << " " << it->section << endl;
// You can also ...
for (int i = 0; i < tl.size(); i++)
cout << tl[i].name << " " << tl[i].dificulty << " " << tl[i].section << endl;
}
void GetTeamInfo(team_list_t& tl)
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open())
{
// Define variables;
string name, dificulty, section;
// Read until EOF
while(fd >> name >> dificulty >> section)
{
// Add teams to the vector/list.
tl.push_back(Team(name, dificulty, section));
}
}
else
{
std::cout << "Mistake can't open file 'Team.txt'\n";
}
}