simplify my code in C++ below - c++

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;
}

Related

List in C++ Standard Template Library (STL). I made the following program and I don't know how to make a function to print the list

#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().

warning C4018: '<': signed/unsigned mismatch ONLY when I include Identical Functions

I am lost, when I ran my program last night it ran fine. When I added the power() function, suddenly lines which ran fine without adding the new code now trigger an error message:
warning C4018: '<': signed/unsigned mismatch
Why?
I feel I don't have the chops to explain this, so please follow the code below.
PLEASE RUN THE CODE WITH AND WITHOUT THIS power() FUNCTION. When run with the power() function, it makes error C4018 on the for loops in the exam() function! When run without the power() function, it runs FINE!!
#include <string>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
using namespace std;
///the offending function///
double power(double base, int exponent)
{
double product;
//double base; int exponent;
std::cout << "enter a value for base: " << endl;
std::cin >> base;
std::cout << "enter exponenent: " << endl;
std::cin >> exponent;
double result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * base;
//product = base exponent;
}
std::cout << product;
return product;
}
///after here, things run fine if you X out the aforementioned function! Wow!
void exam()
{
std::vector<int> scores;
int F;
F = 0; //string names;
std::cout << "enter exam scores int:" << endl;
//std::vector <string> names;
while (F != -1)
{
std::cout << "Enter a new exame score:" << endl;
std::cin >> F;
scores.push_back(F);
}
if (F == -1)
{
std::cout << "end of score entering" << endl;
}
for (int i = 0; i < scores.size(); i++)
{
std::cout << scores[i];
}
/*
while (i < scores.size())
{
std::cout << scores[i];
i++;
}
*/
std::cout << "yay you made this work!!!!!!!!!!!!!" << endl;
}
int multiply()
{
int a;
int b;
a = 8;
b = 4;
std::cout << a * b << endl;
std::cout << "f*** yeah" << endl << endl;
return 0;
}
void test()
{
std::vector<int> newvector;
int T;
std::cout << "enter vector variables: " << endl;
std::cin >> T;
newvector.push_back(T);
while (T != -1)
{
std::cout << "enter new vector variables T " << endl;
std::cin >> T;
newvector.push_back(T);
if (T == -1)
{
newvector.pop_back();
}
}
std::cout << "end of NewVector data inputs:" << endl;
for (int W = 0; W < newvector.size(); W++)
{
std::cout << newvector[W] << endl;
}
}
int main()
{
power(2, 3);
exam();
/*int result = multiply();
std::cout << "endl ;" << endl;
test();
system("pause"); */
multiply();
string name;
int a;
std::cout << "enter a variable for your name: " << endl;
std::getline(cin, name);
if (name == "aaron")
{
std::cout << " what a dumb name, aAron?" << endl;
}
else if (name == "todd")
{
std::cout << "what a dottly name, Todd" << endl;
}
else
{
std::cout << "your name = " << name << endl;
}
//std::vector <string>
std::vector<int> asdf;
std::cout << "enter an int for a" << endl;
std::cin >> a;
asdf.push_back(a);
while (a != -1)
{
std::cout << "enter another A: " << endl;
std::cin >> a;
asdf.push_back(a);
if (a == -1)
{
asdf.pop_back();
}
} //set var; checks if d<size(); if so, JUMP to std::cout<<; when finished with body, find after size(); == "d++", then refer back to declaration)
/*/ for(int G = 0; G<asdf.size(); G++)
{
std::cout << asdf[G] << endl;
} */
for (int i = 0; i < asdf.size(); i++)
{
std::cout << asdf[i] << "f*** it works!!!!!! " << endl;
}
for (int d = 0; d < asdf.size(); d++)
{ //htt ps://youtu.be/_1AwR-un4Hk?t=155
std::cout << asdf[d] << ", ";
}
std::cout << endl;
std::cout << std::accumulate(asdf.begin(), asdf.end(), 0);
//std::cout<<
system("pause");
return 0;
}
The presence of the power function should have no effect on this problem. Possibly you aren't seeing the warnings because without the power function the program does not compile.
In
for (int W = 0; W < newvector.size(); W++)
newvector.size() returns an unsigned integer. int W is a signed integer. You're getting exactly what you asked for.
You can change int W to vector<int>::size_type W (but the less verbose size_t W should also work) to make the error message go away, but this is an error where you would likely have to add more than 2 billion items to the vector to see manifest.
Solution:
for (vector<int>::size_type W = 0; W < newvector.size(); W++)
However this is a good place for a range-based for loop
for (const auto &val: newvector)
{
std::cout << val << endl;
}
By letting the compiler figure out all the sizes and types your life is much easier.
This is repeated several times throughout the code.
Re: WHEN RUN, It makes error C4018 -
YOU made that error (warning, actually), not "it".
That warning is reported by compiler, so you haven't run anything yet...
Your newly added function uses uninitialized variable product; in my version of Visual Studio it is an error.

Doesn't seem to be working using ifstream fin; and fin.open("filename");

I have a program for my class to read in information from a file, as an array, using a function and I've coded this the same way I did for classes last year and I'm not sure why it's not working. I'm supposed to also add more to this but wanted to try to figure out why it's not working with what it already has.
I don't think it's reading the file in because nothing comes out on the output file or the window that pops up when it runs.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
const int maxs = 50;
struct stype
{
int crn;
string name;
int crhrs;
int numstu;
int stucrhrs;
string prof;
};
stype initrec = { 0.0, "course", 0.0, 0.0, 0.0, "prof" };
void initem(stype p[], int &numc)
{
int i;
for (i = 0; i < maxs; i++) p[i] = initrec;
numc = 0;
}
void readem(stype p[], int &numc)
{
int i = 0;
ifstream fin;
fin.open("program1.dat");
while (!fin.eof())
{
fin >> p[i].crn >> p[i].name >> p[i].crhrs >> p[i].numstu >> p[i].stucrhrs >> p[i].prof;
i++;
}
numc = i;
cout << "readem reached " << endl;
}
void printem(stype p[], int &numc, ofstream &fout)
{
int i;
for (i = 0; i < numc; i++)
{
fout << left << setw(10) << p[i].crn << left << setw(15) << p[i].name << left
<< setw(15) << p[i].numstu << right << setw(2) << p[i].crhrs << right <<
setw(2) << p[i].stucrhrs << right << setw(10) << p[i].prof << endl;
}
cout << "printem reached " << endl;
}
void swapem(stype &a, stype &b)
{
stype temp;
temp = a;
a = b;
b = temp;
cout << "swapem reached " << endl;
}
void sortem()
{
cout << "sortem reached " << endl;
}
void getaverage()
{
cout << "getaverage reached " << endl;
}
void credithours()
{
cout << "Credit hours totalled. " << endl;
}
void main()
{
int crn[maxs], crhrs[maxs], stucrhrs[maxs];
string name[maxs], prof[maxs];
stype p[maxs];
int numc;
ofstream fout;
fout.open("program1.out");
fout.setf(ios::fixed);
fout.precision(2);
initem(p, numc);
readem(p, numc);
printem(p, numc, fout);
getaverage();
sortem();
printem(p, numc, fout);
system("pause");
}

Trying to make string array passed through methods C++

I'm trying to read names and ages from user, until user inputs "stop". Then just print all these values. Please help me , I'm just the beginner in C++
// Pass.cpp
// Reading names and ages from user and outputting them
#include <iostream>
#include <iomanip>
#include <cstring>
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using std::strcmp;
char** larger(char** arr);
int* larger(int* arr);
void read_data(char*** names, int** ages);
void print_data(char*** names, int** ages);
int main()
{
char** names = new char*[5];
char*** p_names = &names;
int* ages = new int[5];
int** p_ages = &ages;
read_data(p_names,p_ages);
print_data(p_names,p_ages);
}
void read_data(char*** names, int** ages)
{
const char* sent = "stop";
const int MAX = 15;
int count = 0;
char UI[MAX];
cout << "Enter names and ages."
<< endl << "Maximum length of name is " << MAX
<< endl << "When stop enter \"" << sent << "\".";
while (true)
{
cout << endl << "Name: ";
cin.getline(UI,MAX,'\n');
if (!strcmp(UI, sent))
break;
if (count + 1 > sizeof (&ages) / sizeof (&ages[0]))
{
*names = larger(*names);
*ages = larger(*ages);
}
*names[count] = UI;
cout << endl << "Age: ";
cin >> *ages[count++];
}
}
void print_data(char*** names, int** ages)
{
for (int i = 0; i < sizeof(*ages) / sizeof(*ages[0]);i++)
{
cout << endl << setw(10) << "Name: " << *names[i]
<< setw(10) << "Age: " << *ages[i];
}
}
char** larger(char** names)
{
const int size = sizeof(names) / sizeof(*names);
char** new_arr = new char*[2*size];
for (int i = 0; i < size; i++)
new_arr[i] = names[i];
return new_arr;
}
int* larger(int* ages)
{
const int size = sizeof(ages) / sizeof(*ages);
int* new_arr = new int[2 * size];
for (int i = 0; i < size; i++)
new_arr[i] = ages[i];
return new_arr;
}
You are really over complicating things.
Given the original problem:
Write a program that reads a number (an integer) and a name (less than
15 characters) from the keyboard. Design the program so that the data
is done in one function, and the output in another. Store the data in
the main() function. The program should end when zero is entered for
the number. Think about how you are going to pass the data between
functions
The problem wants you to think about passing parameters to functions. A simple solution would be:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
// Pass in a char array and an integer reference.
// These values will be modified in the function
void read_data(char name[], int& age)
{
cout << endl << "Age: ";
cin >> age;
cin.ignore();
cout << endl << "Name: ";
cin.getline(name, 16);
}
// Pass a const array and an int value
// These values will not be modified
void print_data(char const *name, int age)
{
cout << endl << setw(10) << "Name: " << name
<< setw(10) << "Age: " << age;
}
int main()
{
char name[16];
int age;
cout << "Enter names and ages."
<< endl << "Enter 0 age to quit.";
do {
read_data(name, age);
print_data(name, age);
} while (0 != age)
}
EDIT: Modified per user3290289's comment
EDIT2: Storing data in an array
// Simplify by storing data in a struct (so we don't have to manage 2 arrays)
struct Person {
char name[16];
int age;
};
// Returns how many People were input
int read_data(Person*& arr)
{
int block = 10; // How many persons to allocate at a time
arr = NULL;
int arr_size = 0;
int index = 0;
while (true) {
if (index == arr_size) {
arr_size += block;
arr = (Person *)realloc(arr, arr_size * sizeof(Person)); // Reallocation
// Should check for error here!
}
cout << endl << "Age: ";
cin >> arr[index].age;
cin.ignore();
if (0 == arr[index].age) {
return index;
}
cout << endl << "Name: ";
cin.getline(arr[index++].name, 16);
}
}
void print_data(Person *arr, int count)
{
for (int i = 0; i < count; i++) {
cout << endl << setw(10) << "Name: " << arr[i].name
<< setw(10) << "Age: " << arr[i].age;
}
}
int main()
{
Person *arr;
int count = read_data(arr);
print_data(arr, count);
free(arr); // Free the memory
}
try this:
#include <iostream>
#include <iomanip>
#include <vector>
#include <sstream>
using std::cout;
using std::cin;
using std::endl;
using std::setw;
using std::strcmp;
void read_data(std::vector<std::string> &names, std::vector<int> &ages);
void print_data(std::vector<std::string> &names, std::vector<int> &ages);
int main()
{
std::vector<std::string> names;
std::vector<int> ages;
read_data(names, ages);
print_data(names, ages);
}
void read_data(std::vector<std::string> &names, std::vector<int> &ages)
{
const char* sent = "stop";
cout << "Enter names and ages."
<< endl << "When stop enter \"" << sent << "\".";
while (true)
{
std::string input;
cout << endl << "Name: ";
std::getline(cin, input);
if (!strcmp(input.c_str(), sent))
break;
names.push_back(input);
cout << endl << "Age: ";
std::string age;
std::getline(cin, age);
ages.push_back(atoi(age.c_str()));
}
}
void print_data(std::vector<std::string> &names, std::vector<int> &ages)
{
for (int i = 0; i < names.capacity() ; i++)
{
cout << endl << setw(10) << "Name: " << names.at(i)
<< setw(10) << "Age: " << ages.at(i);
}
}
One problem I see is this if statement:
if (count + 1 > sizeof (&ages) / sizeof (&ages[0]))
&ages is the address of an int**, a pointer, and so it's size is 8 (usually) as that is the size of a pointer type. The function does not know the size of the array, sizeof will only return the correct answer when ages is declared in the same scope.
sizeof(&ages) / sizeof(&ages[0])
will always return 1
I believe one natural solution about this problem is as follows:
create a "std::map" instance. Here std::map would sort the elements according to the age. Here my assumption is after storing the data into the container, you would like to find about a particular student age/smallest/largest and all various manipulation with data.Just storing and printing the data does not make much sense in general.
create a "std::pair" and take the both input from the user into the std::pair "first" and "second" member respectively. Now you can insert this "std::pair" instance value into the above "std::map" object.
While printing, you can now fetch the each element of "std::map" in the form of "std::pair" and then you can display pair "first" and "second" part respectively.

why is getline() not working in my little experiment?

//////////////////////////////////////////////////////////////////
// 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?