I recently started C++, moving from JavaScript, so I'm a little bit confused.
I'm trying to make a number guessing game, and my actual error is something like:
main.cpp:14:67: error: invalid operands of types ‘const char*’ and ‘const char [2]’ to binary ‘operator+’
cout << "Perfect, now your playing with numbers up to " + range + "."
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
$ g++ main.cpp
main.cpp: In function ‘int main()’:
main.cpp:14:67: error: invalid operands of types ‘const char*’ and ‘const char [2]’ to binary ‘operator+’
cout << "Perfect, now your playing with numbers up to " + range + "."
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
I have no idea if it helps, but I'm going to attach my code below:
#include <iostream>
using namespace std;
void startGame(int random);
int generateNo(int range);
int main() {
int range;
cout << "WELCOME TO NUMBER GUESSING GAME!" << endl;
cout << "The calculator is going to generate a random number and you'll have to guess it!" << endl;
cout << "Please enter the range of numbers you want to play (ex: 10)" << endl;
cin >> range;
int solution = generateNo(range);
cout << "Perfect, now your playing with numbers up to " + range + "."
cout << "GOOD LUCK :)" << endl;
startGame(solution);
return 0;
}
int generateNo(int range) {
return rand() % range + 1;
}
void startGame(int random) {
int inputNo;
cin >> inputNo;
for( int a = 0; ; a++) {
if(inputNo == random) {
cout << "Congrats! You've guessed the number!" << endl;
break;
} else if(inputNo > random) {
cout << "Hooolly! WHAT'S with this giant number" << endl;
startGame(random);
break;
} else {
cout << "Good number, but had your little brain considered to make it bigger!?" << endl;
startGame(random);
break;
}
}
}
You can chain calls to <<:
cout << "Perfect, now your playing with numbers up to " << range << ".";
If you want to first build a string (no reason to do that here), you first need to build a string:
std::string text = std::string{"Perfect, now ..."} + std::to_string(range) + ".";
std::cout << text;
In your code you are trying to add a string literal (type is char[N]) with an integer. There is no operator+ to concatenate an integer to a string literal.
C++ doesn't overload the + operator between all the arbitrary types, and doesn't implicitly convert everything to strings when you try to print it out. Luckily, for all the built-in types, you could just write them to the output stream using the << operator (and override it for your own types):
cout << "Perfect, now your playing with numbers up to "
<< range // Note the use of "<<" and not of "+"
<< "."
<< "GOOD LUCK :)"
<< endl;
Related
Im having trouble with this recursion code. Basically I want the computer to "guess" in as little steps as possible the number that I am thinking of. However, everything works except the final output. The bounds are fine, and it narrows down the guess until it asks me if the number im thinking of is say 16, if I input "=" it should output 16 instead it always outputs 50. Could anyone help me locate the error?
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
unsigned int search (unsigned int boundInf, unsigned int boundSup);
int main ()
{
int b;
b = search (1, 100);
cout << "Your number must be : " << b << endl;
}
unsigned int search (unsigned int boundInf, unsigned int boundSup)
{
string magnitude;
int b;
b = (boundSup + boundInf) / 2;
cout << "Is your number <, > or = to " << b << "? ";
cin >> magnitude;
if (magnitude == "<") {
cout << "Between " << boundInf << " and " << b << endl;
search (boundInf, b);
}
else if (magnitude == ">") {
cout << "Between " << b << " and " << boundSup << endl;
search (b, boundSup);
}
return b;
}
You forgot to change the value of b when going deeper into the recursive function, this can be easily fixed by changing the search function like so:
unsigned int search(unsigned int boundInf, unsigned int boundSup)
{
string magnitude;
int b;
b = (boundSup + boundInf) / 2;
cout << "Is your number <, > or = to " << b << "? ";
cin >> magnitude;
if (magnitude == "<")
{
cout << "Between " << boundInf << " and " << b << endl;
b = search(boundInf, b);
}
else if (magnitude == ">")
{
cout << "Between " << b << " and " << boundSup << endl;
b = search(b, boundSup);
}
return b;
}
Here's the code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}
The only reason I gave values to keyArray was that I read in answer to a similar question that you have to initialize an array with data before you use it. But it made no difference. The output is just junk symbols whether you initialize or not.
The compiler is Visual Studio Community 2017. Thanks for any help.
The error is not in your logic but rather in your debugging output. Since the other answers focus on how to fix it, I'll rather explain what happens instead. There seems to be a misunderstanding about the way strings work in C++.
The failure is in this operation:
keyArray[0] + "\n"
Internally, string literals are arrays of characters, in this case const char[2], consisting of the newline and a terminating '\0' null terminator. When you then try to add the integer and this array together, the array will be represented by a pointer to its first element, i.e. it will decay to const char* in order to be used as the second argument to the plus operator used in your code.
So for the compiler, this line will need operator+(int, const char*). But the result of that will be const char*, the input pointer offset by the integer, as that is the operation that happens when adding integers to pointers.
So instead of printing the number and then the string, it will try to access a string that does not exist as the pointer now pointer behind the string "\n" and thus into some arbitrary memory.
Instead of doing
cout << keyArray[0] + "\n"
do:
cout << keyArray[0] << "\n"
or
cout << keyArray[0] << endl
You can't concatanate an integer with a string. That's why you got garbage output
Try this first:
cout << keyArray[0] << "\n";
If you are using compilers that support C++ 11 then try using std::to_string(...) to make a string from an integer before doing the addition:
cout << (std::to_string(keyArray[0]) + "\n");
you cannot concatenate int with string.
change
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
to
cout << keyArray[0] << "\n"
<< keyArray[1] << "\n"
<< keyArray[2] << "\n"
<< keyArray[3] << "\n"
<< keyArray[4] << "\n"
<< keyArray[5] << "\n"
<< keyArray[6] << endl;
You need to convert the integers into a string. Using a relatively recent version of C++:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << std::to_string(keyArray[0]) + "\n";
cout << std::to_string(keyArray[1]) + "\n";
cout << std::to_string(keyArray[2]) + "\n";
cout << std::to_string(keyArray[3]) + "\n";
cout << std::to_string(keyArray[4]) + "\n";
cout << std::to_string(keyArray[5]) + "\n";
cout << std::to_string(keyArray[6]) + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}
I have a problem passing a pointer to a function. Here is the code.
#include <iostream>
using namespace std;
int age = 14;
int weight = 66;
int SetAge(int &rAge);
int SetWeight(int *pWeight);
int main()
{
int &rAge = age;
int *pWeight = &weight;
cout << "I am " << rAge << " years old." << endl;
cout << "And I am " << *pWeight << " kg." << endl;
cout << "Next year I will be " << SetAge(rAge) << " years old." << endl;
cout << "And after a big meal I will be " << SetWeight(*pWeight);
cout << " kg." << endl;
return 0;
}
int SetAge(int &rAge)
{
rAge++;
return rAge;
}
int SetWeight(int *pWeight)
{
*pWeight++;
return *pWeight;
}
My compiler outputs this:
|| C:\Users\Ivan\Desktop\Exercise01.cpp: In function 'int main()':
Exercise01.cpp|20 col 65 error| invalid conversion from 'int' to 'int*' [-fpermissive]
|| cout << "And after a big meal I will be " << SetWeight(*pWeight);
|| ^
Exercise01.cpp|9 col 5 error| initializing argument 1 of 'int SetWeight(int*)' [-fpermissive]
|| int SetWeight(int *pWeight);
|| ^
PS: In real life I wouldnt use this but I got into it and I wanna get it working this way.
You shouldn't dereference the pointer. It should be:
cout << "And after a big meal I will be " << SetWeight(pWeight);
Also, in SetWeight(), you are incrementing the pointer instead of incrementing the value, it should be:
int SetWeight(int *pWeight)
{
(*pWeight)++;
return *pWeight;
}
int *pWeight = &weight;
This declares pWeight as a pointer to an int. SetWeight actually takes a pointer to an int, so you can just pass pWeight straight in without any other qualifiers:
cout << "And after a big meal I will be " << SetWeight(pWeight);
First I took your feedback and changed:
cout << "And after a big meal I will be " << SetWeight(*pWeight);
// to
cout << "And after a big meal I will be " << SetWeight(pWeight);
// But after that I changed also:
*pWeight++;
// to
*pWeight += 1;
The * symbol can have two different meanings in C++. When used in a function header, they indicate that the variable being passed is a pointer. When used elsewhere in front of a pointer it indicates that to which the pointer is pointing. It seems you may have confused these.
I've been having a slight issue with my program, what I'm trying to do is develop a way for users to simulate the possible strengths of passwords. This is assuming that all passwords are permutations (weird I know, but I presume that this is to stop data from becoming even more unwieldy.) using the equation...
//n!/(n-r)! when n! = (e^-n)*(n^n) sqrt(2(pi)n). When n is number of characters in use and r is length of password
No matter what I put I receive nan as an answer. I thought that perhaps my equation was off (maybe somehow I was dividing by zero) so I reworked it and simplified it a great deal. But that didn't seem to be the problem, though I feel that this got me closer to being correct. But I had the thought that maybe numeric overflow is having an effect here? But I really don't know how to fix something like that. I tried jumping from different data types but nothing seemed to work.
I have a problem with the modulus too. It returns back numbers less than zero for time, so with my noobish knowledge that tells me that maybe I'm overflowing it again but how else am I going to use % without defining it as an int? Maybe fixing the above problem will work out this one?
I would be beyond grateful for any help given to me. How does one go about dealing with return values of nan? Is there a step by step status quo for solving it? Is it pretty much always overflow or could it be something else?
The code itself.
#include <iostream>
#include <cmath>
using namespace std;
const int SECONDS_IN_YEAR = 31556926;
const int SECONDS_IN_DAY = 86400;
const int SECONDS_IN_HOUR = 3600;
const int SECONDS_IN_MIN = 60;
int main()
{
int passwordLength ,characterSymbols;
double instructionsPerSecond, instructionSuccess;
////////////////////////////////////////////////////////////////////////////////
//Equations needed
// n!/(n-r)!
//n is the number of letters in the alphabet
//and r is the number of letters in the password
// n! = (e^-n)*(n^n) sqrt(2(pi)n)
double numeratorFactorial = (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
// (n-r)
double characterMinusLength= (characterSymbols-passwordLength);
// (n-r)! = (e^-(n-r)) * ((n-r)^(n-r)) * sqrt(2(pi)(n-r))
double denominatorFactorial = ((pow(M_E, -(characterMinusLength)))*
(pow((characterMinusLength),(characterMinusLength)))
* (sqrt(2*M_PI*(characterMinusLength))));
// n!/(n-r)!
long double passwordPermutation = (numeratorFactorial / denominatorFactorial);
// (passwords)* (instructions/Password) * (seconds/instruction) = sec
int passwordSeconds = (passwordPermutation * instructionSuccess)
*(1/instructionsPerSecond);
int passwordMin = passwordSeconds / SECONDS_IN_MIN ;
int passwordHour = passwordSeconds / SECONDS_IN_HOUR;
int passwordDay = passwordSeconds / SECONDS_IN_DAY ;
int passwordYear = passwordSeconds / SECONDS_IN_YEAR;
////////////////////////////////////////////////////////////////////////////////
//Explain purpose of program
cout << "This program is designed to simulate the strength of passwords." << endl;
//Ask for alphabet
cout << "But first, share with me the max number of characters you'd be using."
<< endl;
cin >> characterSymbols;
//Reflect information
cout << "We will be using " << characterSymbols << " character symbols to "
<< " construct the password.\n" << endl;
///////////////////////////////////////////////////////////////////////////////
//Input length of password
cout << "\n\nWill you give me the length of proposed password?" << endl;
cin >> passwordLength;
//Repeat information
cout << "The password length will be " << passwordLength << "." <<endl;
//cout permutations
cout << "This would lead to " << passwordPermutation << " unique password\n"
<< endl;
////////////////////////////////////////////////////////////////////////////////
//Ask for computer strength
cout << "How powerful is this computer? How many instructions per second " << endl;
cout << "can it accomplish?" << endl;
cin >> instructionsPerSecond;
//Read out computer strength
cout << "The computer can do " << instructionsPerSecond << " instructions/second"
<< endl << endl;
////////////////////////////////////////////////////////////////////////////////
//Ask for instructions/password
cout << "The number of instructions needed to test your password is." << endl
<< endl;
cin >> instructionSuccess;
//reflect
cout << "This computer can do " << instructionSuccess
<< " instructions/password" << endl;
////////////////////////////////////////////////////////////////////////////////
cout << "\n\nThe amount of seconds it'll take to crack this passcode is... "
<< endl << passwordSeconds << " seconds.\n\n\n\n\n" << endl;
////////////////////////////////////////////////////////////////////////////////
//Reflect all information in an easily readable table
cout << "Number of character symbols using... " << characterSymbols << endl;
cout << "Length of password... " << passwordLength << endl;
cout << "Number of permutations... " << passwordPermutation << endl;
cout << "Instructions per second... " << instructionsPerSecond << endl;
cout << "Instructions per password..." << instructionSuccess << endl;
cout << endl << endl << endl;
////////////////////////////////////////////////////////////////////////////////
//Add in conversions for min, hour, day, years
cout << "Number of seconds to break..." << passwordSeconds << endl;
cout << "Converted to minutes..." << passwordMin << endl;
passwordMin = passwordSeconds / SECONDS_IN_MIN;
passwordSeconds = passwordSeconds % SECONDS_IN_MIN;
cout << "Converted to hours..." << passwordHour << endl;
passwordHour = passwordSeconds / SECONDS_IN_HOUR;
passwordSeconds = passwordSeconds % SECONDS_IN_MIN;
cout << "Converted to days..." << passwordDay << endl;
passwordDay = passwordSeconds / SECONDS_IN_DAY;
passwordSeconds = passwordSeconds % SECONDS_IN_DAY;
cout << "Converted to years..." << passwordYear << endl;
passwordYear = passwordSeconds / SECONDS_IN_YEAR;
passwordSeconds = passwordSeconds % SECONDS_IN_YEAR;
return (0);
}
"nan" stands for "not a number". This is happening because you have declared the variables characterSymbols and passwordLength without giving them an initial value.
You must initialize any variable before you use it - if you don't then you will have undetermined behavior. For example:
int x;
int y;
int z = x + y;
There is no way to predict what z will be equal to here because we don't know what x or y are equal to. In the same way, your code should be something like:
int characterSymbols = 10; //or whatever you want the initial value to be
...
double numeratorFactorial = (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
In this way, numeratorFactorial will have a valid value.
It appears you think you are declaring "equations" when you are actually declaring variables. You write:
double numeratorFactorial = (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
But characterSymbols isn't defined, only "declared". characterSymbols is declared above it, but it doesn't have a value... yet. Later on you use cin to get a value into it, but when you first declare numeratorFactorial you can't simply expect the program to insert the value into numeratorFactorial when characterSymbols changes.
Some definitions are probably in order: The statement double numeratorFactorial = some_value; creates a variable named numeratorFactorial and uses some_value to fill that variable immediately. What you want is a function, a logical statement that you can "pass values" to so values are generated when you need them. For example, for your numerator factorial:
double numeratorFactorial(double characterSymbols) {
return (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
}
int main() {
std::cout << "Numerator Factorial test: " << numeratorFactorial(5.0) << std::endl;
}
Note that you cannot declare a function within the main function.
This sort of thing is programming fundamentals, and it seems like you are trying to run before you've learned to walk. Get a good book like C++ Primer and pace yourself.
I've been trying to format the output to the console for the longest time and nothing is really happening. I've been trying to use as much of iomanip as I can and the ofstream& out functions.
void list::displayByName(ostream& out) const
{
node *current_node = headByName;
// I have these outside the loop so I don't write it every time.
out << "Name\t\t" << "\tLocation" << "\tRating " << "Acre" << endl;
out << "----\t\t" << "\t--------" << "\t------ " << "----" << endl;
while (current_node)
{
out << current_node->item.getName() // Equivalent tabs don't work?
<< current_node->item.getLocation()
<< current_node->item.getAcres()
<< current_node->item.getRating()
<< endl;
current_node = current_node->nextByName;
}
// The equivalent tabs do not work because I am writing names,
// each of different length to the console. That explains why they
// are not all evenly spaced apart.
}
Is their anything that I can use to get it all properly aligned with each other?
The functions that I'm calling are self-explanatory and all of different lengths, so that don't align very well with each other.
I've tried just about everything in iomanip.
Think of it like using Microsoft Excel :)
You think of your stream as fields. So you set the width of the field first then you insert your text in that field. For example:
#include <iostream>
#include <iomanip>
#include <string>
int main()
{
using namespace std;
string firstName = "firstName",
secondName = "SecondName",
n = "Just stupid Text";
size_t fieldWidth = n.size(); // length of longest text
cout << setw(fieldWidth) << left << firstName << endl // left padding
<< setw(fieldWidth) << left << secondName << endl
<< setw(fieldWidth) << left << n << endl;
cout << setw(fieldWidth) << right << firstName << endl // right padding
<< setw(fieldWidth) << right << secondName << endl
<< setw(fieldWidth) << right << n << endl;
}
......
......
The field width means nothing but the width of the text + spaces. You could fill anything other than spaces:
string name = "My first name";
cout << setfill('_') << setw(name.size() + 10) << left << name;
.....
output::
My first name__________
......
I think the best way is to figure out your format then, write a new formatter that does all what you want:
#include <iostream>
#include <iomanip>
#include <string>
std::ostream& field(std::ostream& o)
{
// usually the console is 80-character wide.
// divide the line into four fields.
return o << std::setw(20) << std::right;
}
int main()
{
using namespace std;
string firstName = "firstName",
secondName = "SecondName",
n = "Just stupid Text";
size_t fieldWidth = n.size();
cout << field << firstName << endl
<< field << secondName << endl
<< field << n << endl;
}
If you started thinking about parametrized manipulators, only that accept one int or long parameter are easy to implement, other types are really obscure if you are not familiar with streams in C++.
Boost has a format library that allows you to easily format the ourput like the old C printf() but with type safety of C++.
Remember that the old C printf() allowed you to specify a field width. This space fills the field if the output is undersized (note it does not cope with over-sized fields).
#include <iostream>
#include <iomanip>
#include <boost/format.hpp>
struct X
{ // this structure reverse engineered from
// example provided by 'Mikael Jansson' in order to make this a running example
char* name;
double mean;
int sample_count;
};
int main()
{
X stats[] = {{"Plop",5.6,2}};
// nonsense output, just to exemplify
// stdio version
fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
stats, stats->name, stats->mean, stats->sample_count);
// iostream
std::cerr << "at " << (void*)stats << "/" << stats->name
<< ": mean value " << std::fixed << std::setprecision(3) << stats->mean
<< " of " << std::setw(4) << std::setfill(' ') << stats->sample_count
<< " samples\n";
// iostream with boost::format
std::cerr << boost::format("at %p/%s: mean value %.3f of %4d samples\n")
% stats % stats->name % stats->mean % stats->sample_count;
}
Give up on the tabs. You should be able to use io manipulators to set the field width, the fill character, and the format flag (to get left or right justification). Use the same values for the headings as you do for the data, and everything should come out nicely.
Also beware that you've switched Rating and Acres in your example.
You can write a procedure that always print the same number of characters to standard output.
Something like:
string StringPadding(string original, size_t charCount)
{
original.resize(charCount, ' ');
return original;
}
And then use like this in your program:
void list::displayByName(ostream& out) const
{
node *current_node = headByName;
out << StringPadding("Name", 30)
<< StringPadding("Location", 10)
<< StringPadding("Rating", 10)
<< StringPadding("Acre", 10) << endl;
out << StringPadding("----", 30)
<< StringPadding("--------", 10)
<< StringPadding("------", 10)
<< StringPadding("----", 10) << endl;
while ( current_node)
{
out << StringPadding(current_node->item.getName(), 30)
<< StringPadding(current_node->item.getLocation(), 10)
<< StringPadding(current_node->item.getRating(), 10)
<< StringPadding(current_node->item.getAcres(), 10)
<< endl;
current_node = current_node->nextByName;
}
}