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

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.

Related

vector<string> in a struct doesn't work properly

I declared a vector<string> and I cannot even compile it. I tried many ways but none of them worked.
I'm trying to write out the x.surname.push_back(word)[i] but it's definetly written wrongly and I have no idea how to write it properly and make it possible to compile.
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int number, i = 0;
string word;
struct donators {
vector<string> surname;
vector<int> amount;
} x;
cout << "How many donators do you want to register? " << endl;
cin >> number;
for (i = 0; i < number; i++) {
cout << "Surname: ";
cin >> word;
x.surname.push_back(word)[i];
cout << "Amount: ";
x.amount.push_back(i);
cin >> x.amount[i];
}
cout << "OUR GORGEUS DONATORS: " << endl;
for (i = 0; i < number; i++) {
if (x.amount[i] >= 10000) {
cout << "Surname: " << x.surname(word)[i];
cout << "Amount: " << x.amount[i] << endl;
}
else if (x.amount[i] < 10000) {
cout << "Lack of surnames!" << endl;
}
}
cout << "OUR CASUAL DONATORS: " << endl;
for (i = 0; i < number; i++) {
if (x.amount[i] < 10000) {
cout << "Surname: " << x.surname(word)[i];
cout << "Amount: " << x.amount[i] << endl;
} else if (x.amount[i] >= 10000) {
cout << "Lack of surnames!" << endl;
}
}
return 0;
}
And one more thing. How to make sentence "Lack of surnames!" to be written out once? In some cases, it is written out twice or more times what is redundant.
You are putting [i] at seemingly random places in your code. Such as in x.surname.push_back(word)[i];. Don't add things like this to your code if you're unsure about what they're doing.
The x.surname(word)[i] construct are also wrong. What's x.surname(word) supposed to be? This syntax is for function calls. surname, however, is not a function. It's a std::vector<std::string>. Just put x.surname[i] instead.
And one more thing. How to make sentence "Lack of surnames!" to be
written out once? In some cases, it is written out twice or more times
what is redundant.
That's because you write it for every donor that doesn't fit the criterion. Instead, keep track if any donor fits the criterion and only print it when none ends up fitting. You can do it like this:
bool HasGorgeousDonators = false;
And then in the loop:
if (x.amount[i] >= 10000)
{
cout << "Surname: " << x.surname[i];
cout << "Amount: " << x.amount[i] << endl;
HasGorgeousDonators = true;
}
And after the loop:
if (!HasGorgeousDonators)
cout << "Lack of surnames!" << endl;
Likewise for the other loop. Also, please consider the following Q&A:
Why is "using namespace std;" considered bad practice?
It seems like you are writing C with some C++ help functions. However C++ is a different language. Sure, it supports some C structures, but there's so much more.
Take a look at some of my suggestions for implementation and compare it to your code:
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
template<typename T>
T ReadCin(std::string_view const& sv = "") {
T retVal;
if (!sv.empty()) std::cout << sv;
std::cin >> retVal;
return retVal;
}
class Donator {
private:
std::string surname{};
int amount{};
public:
constexpr bool IsGenerous() const noexcept { return amount >= 10000; }
void Read() noexcept {
surname = ReadCin<decltype(surname)>("Surname: ");
amount = ReadCin<decltype(amount)>("Amount: ");
}
friend std::ostream& operator<<(std::ostream& out, Donator const& donator) noexcept {
out << "Surname: " << donator.surname << ", " << "Amount: " << donator.amount;
return out;
}
};
int main() {
std::vector<Donator> donators(ReadCin<int>("How many donators do you want to register?\n"));
for (auto& donator : donators) donator.Read();
std::cout << "OUR GENEROUS DONATORS:\n";
std::copy_if(std::cbegin(donators), std::cend(donators), std::ostream_iterator<Donator>(std::cout, "\n"),
[](Donator const& donator) { return donator.IsGenerous(); });
std::cout << "OUR CASUAL DONATORS:\n";
for (auto const& donator : donators) if (!donator.IsGenerous()) std::cout << donator << '\n'; //alternative
}
I tried to include some of the possibilities using C++. I would really advise you to get a good book on C++.

simplify my code in C++ below

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

Error Variable is Protected

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
void armySkirmish();
void battleOutcome();
string commander = "";
int numberOfHumans = 0;
int numberOfZombies = 0;
class ArmyValues
{
protected:
double attackPower;
double defensePower;
double healthPoints;
public:
void setAttackPower(double a)
{
attackPower = a;
}
void setDefensePower(double d)
{
defensePower = d;
}
void setHealthPoints(double h)
{
healthPoints = h * (defensePower * .1);
}
};
class Zombies: public ArmyValues
{
};
class Humans: public ArmyValues
{
};
int main(int argc, char ** argv)
{
cout << "Input Commander's Name: " << endl;
cin >> commander;
cout << "Enter Number of Human Warriors: " << endl;
cin >> numberOfHumans;
cout << "Enter Number of Zombie Warriors: " << endl;
cin >> numberOfZombies;
armySkirmish();
battleOutcome();
return 0;
}
void armySkirmish()
{
cout << "\nThe Humans tense as the sound of the undead shuffle towards them." << endl;
cout << commander << " shuffles forward with a determined look." << endl;
cout << "The undead form up into ranks and growl a war chant!" << endl;
cout << commander <<" shouts, CHARGE!!!" << endl;
cout << endl;
cout << "Warriors from both sides blitz across the field!" << endl;
cout << endl;
cout << "*The Carnage has begun!*" << endl;
cout << "*Steal, Sparks, and Flesh flies" << endl;
}
void battleOutcome()
{
int zombieLives = numberOfZombies;
int humanLives = numberOfHumans;
int randomNumber = 0;
int humanDeath = 0;
int zombieDeath = 0;
double newHumanLife = 0;
double newZombieLife = 0;
Zombies zombieBattleData;
Humans humanBattleData;
srand(time(NULL));
zombieBattleData.setAttackPower(20.0);
humanBattleData.setAttackPower(35.0);
zombieBattleData.setDefensePower(15.0);
humanBattleData.setDefensePower(20.0);
zombieBattleData.setHealthPoints(150.0);
humanBattleData.setHealthPoints(300.0);
while(zombieLives && humanLives > 0)
{
randomNumber = 1+(rand()%10);
if(randomNumber < 6)
{
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
if(newHumanLife <= 0)
{
humanLives--;
humanDeath++;
}
}else
{
newZombieLife = zombieBattleData.healthPoints - humanBattleData.attackPower;
if(newZombieLife <= 0)
{
zombieLives--;
zombieDeath++;
}
}
}
if(zombieLives <= 0)
{
cout << "Humans have emerged victorious!" << endl;
cout << "Human Deaths: " << humanDeath << "Zombie Deaths: " << zombieDeath << endl;
}else if(humanLives <= 0)
{
cout << "Zombies have emerges victorious!" << endl;
cout << "Human Deaths: " << humanDeath << "Zombie Deaths: " << zombieDeath << endl;
}
I know the code wont run properly as of now. What I was doing was a test run to make sure I was receiving no errors. The two errors I'm getting are:
armySimulatorMain.cpp:25:10: error: 'double ArmyValues::healthPoints' is protected
armySimulatorMain.cpp:115:67: error: within this context.
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
This is the case for Attack Power and Health Power however, Defense power is clearing the errors. i don't understand why they are getting flagged. I'm changing the variable through the public function so shouldn't this be allowed?
Also, I'm calling three variables outside of all functions because they are being used by multiple functions. How can I plug those variables somewhere I don't like that they are floating freely above everything?
Thanks guys I can't believe I forgot about getters... Anyway the code runs now much appreciated I'll make sure to remember this time xD
It's not complaining about the line where you set the values; as you say, that uses a public function. But here, you try to read the protected member variables:
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
You only try to read two variables, and those are the ones it complains about.
You'll need a public getter function to read the values.
You need to do something like:
public:
double gethealthPoints()
{
return healthPoints;
}
because attackPower, defensePower, healthPoints are all protected, so if you want to access to any of them you need a getter, otherwise you will always receive an protect error

C++ class and function output issue

I'm having problems with my program's output. It keeps spitting out 12345.
Here's the details:
It's split in three files: program8.cpp (the part that runs tests), myRandom.cpp (implementation of the class), and myRandom.h (specification of the class).
myRandom.h:
#ifndef MYRANDOM_H_
#define MYRANDOM_H_
class myRandom
{
public:
myRandom(); //Constructor
~myRandom(); //Destructor
void seed(unsigned long theSeed); //Mutator for current
unsigned long next(); //Mutator or Accessor for current
int randInt(int start, int end); //Scales result to a range
double randNormal(); //Future expansion
private:
unsigned long current; //Current random #
static const unsigned long a = 1103515245; //Multiplier for LGC
static const unsigned long c = 12345; //Increment for LGC
static const unsigned long m = 2147483648; //Modulus for LGC
};
#endif /* MYRANDOM_H_ */
myRandom.cpp:
#include <iostream>
#include <cstdlib>
#include "myRandom.h"
using namespace std;
myRandom::myRandom() //Constructor
{
current = 0;
}
myRandom::~myRandom() //Destructor
{
}
void myRandom::seed(unsigned long theSeed) //Mutator for current
{
if (theSeed < 0 || theSeed > m-1)
{
// ERROR
return;
}
else
current = theSeed;
}
unsigned long myRandom::next() //Mutator or Accessor for current
{
if (current < 0)
{
cout << "Error: cannot set seed to a negative number" << endl;
return 0;
}
else
{
current = (m*current+c)%m; //Formula
return current;
}
}
int myRandom::randInt(int start, int end) //Scales result to a range
{
if (start >= end)
{
cout << "Error: cannot set start greater than or equal to end" << endl;
return 0;
}
else
{
return ((this->next() % (end - start)) + start);
}
}
double myRandom::randNormal() //Future expansion
{
cout << "Warning: randNormal not implemented" << endl;
return 0;
}
program8.cpp:
#include <iostream>
#include <cstdlib>
#include "myRandom.h"
using namespace std;
int main()
{
myRandom theRand;
unsigned long theSeed;
cout << "Verify that the sequence generated by next() is the same on each run" << endl;
for (int i = 0; i < 5; i++)
{
cout << theRand.next() << endl;
}
cout << "Verify that you can set the seed to 0 and 1" << endl;
theSeed = 0;
cout << theRand.next() << endl;
theSeed = 1;
cout << theRand.next() << endl;
cout << "Verify that attempting to set the seed to -1 generates an error" << endl;
theSeed = -1;
cout << theRand.next() << endl;
cout << "Verify that you can set the seed to m-2 and m-1" << endl;
theSeed = 2147483648-2;
cout << theRand.next() << endl;
theSeed = 2147483648-1;
cout << theRand.next() << endl;
cout << "Verify that attempting to set the seed to m generates and error" << endl;
theSeed = 2147483648;
cout << theRand.next() << endl;
cout << "Verify that next() produces a sequence predicted by hand/calc for the chosen seed" << endl;
cout << "Please enter a seed: ";
cin >> theSeed;
cout << theRand.next() << endl;
cout << "Verify that using start == end generates and error. Set both to 10." << endl;
theRand.randInt(10,10);
cout << theRand.next() << endl;
cout << "Verify that using start > end generates and error. Set start to 10 and end to 5." << endl;
theRand.randInt(10,5);
cout << theRand.next() << endl;
theRand.seed(theSeed);
cout << "Testing randInt for start=0 end=1,000" << endl;
for (int i = 0; i < 5; i++)
{
cout << theRand.randInt(0 , 1000) << endl;
}
return 0;
}
I think the problem lies in the next() function, since that's what gets called all those times in program8.cpp cout statements. I could understand getting 12345 once, but it should be updated once that function runs successive times. I apologize if it's a dumb question. Thank you for your time and patience.
Your problem isn't a code specific one - it is Math-related from here:
current = (m*current+c)%m;
This always returns the value of c if c < m, otherwise (or more generally) it returns c % m. Why? From this theorem:
(m*n + a)%m = a
Example:
m = 10
n = 3
a = 7
(10*3 + 7)%10 = 7
See this for more:
http://en.wikipedia.org/wiki/Modulo_operation

Function counting characters of a string class being skipped?

I was trying to count the number of characters in a string class but for some reason the program is skipping over my function completely. This is just the test code from the main program, it still was giving me the same results. How come the counter function is skipped over?
#include <iostream>
#include <string>
using namespace std;
void prompt(string& dna)
{
cout << "Input: ";
getline(cin, dna);
}
void counter(const string DNA,
int* a_count, int* t_count, int* c_count, int* g_count)
{
for (int i = 0; i < DNA.size(); i++)
{
if (DNA.at(i) == 'a')
{
*a_count++;
}
else if (DNA.at(i) == 't')
{
*t_count++;
}
else if (DNA.at(i) == 'c')
{
*c_count++;
}
else if (DNA.at(i) == 'g')
{
*g_count++;
}
}
}
int main()
{
string dna;
int a = 0;
int t = 0;
int c = 0;
int g = 0;
prompt(dna);
if (! dna.empty())
{
cout << "Before:\n"
<< "A: " << a << endl
<< "T: " << t << endl
<< "C: " << c << endl
<< "G: " << g << endl;
counter(dna, &a, &t, &c, &g);
cout << "\n\nAfter:\n"
<< "A: " << a << endl
<< "T: " << t << endl
<< "C: " << c << endl
<< "G: " << g << endl;
}
system("pause");
return 0;
}
You're applying operator ++ the wrong way. It should be:
if (DNA.at(i) == 'a')
{
(*a_count)++;
}
else if (DNA.at(i) == 't')
{
(*t_count)++;
}
else if (DNA.at(i) == 'c')
{
(*c_count)++;
}
else if (DNA.at(i) == 'g')
{
(*g_count)++;
}
You've got a priority problem between the ++ and * operators. You are incrementing the pointer address, not the value. (*a_count)++; would be correct.
You may find it easier to use reference parameters for the counts instead, since you don't actually need to do any pointer arithetic. ie:
void counter(const string DNA, int& a_count, int& t_count, int& c_count, int& g_count)
And, yes a switch statement would be neater.