This question already has answers here:
Order of evaluation of arguments using std::cout
(5 answers)
Strange output, not as expected
(2 answers)
Undefined behavior and sequence points
(5 answers)
Closed 5 years ago.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 5;
int& b = a;
int* c = &a;
cout << "CASE 1" << endl;
cout << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
b = 10;
cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl << endl;
cout << "CASE 2";
a = 5;
cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
b = 10;
cout << endl << "a is " << a << endl << "b is " << ++b << endl << "c is " << *c << endl << endl;
cout << "CASE 3";
a = 5;
cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
b = 10;
cout << endl << "a is " << a << endl << "b is " << b++ << endl << "c is " << *c << endl;
}
The output:
CASE 1:
a is 5. b is 5. c is 5.
a is 10. b is 10. c is 10.
CASE 2:
a is 5. b is 5. c is 5.
a is 11. b is 11. c is 10.
CASE 3:
a is 5. b is 5. c is 5.
a is 11. b is 10. c is 10.
I understand CASE 1. But I am having difficulty understanding CASE 2 and CASE 3. Can someone explain why doesn't c get updated with new value in both cases?
The evaluation order of operands is unspecified, and you're modifying an object and reading it without those operations being sequenced.
Thus, your program is as undefined as cout << a << a++;, and anything can happen.
I think your problem is due to what is called sequence points. You can have a long read about that in this answer but in a few words it basically states the order or evaluation of the elements of an expression.
Update in your case this order is undefined, although some compilers seem to make it right-to-left.
Here is what I have done so far, I did my best to label each bit of the code. It should also be noted that this was written in XCode, so it's running on a Mac.
/*
Ayush Sharma
4 November 2016
*/
#include <iostream>
#include <ctime>
using namespace std;
int main (){
//clearing the screen
system("clear");
//seeding the random
srand((unsigned int)time(NULL));
//variables & arrays
char answer;
int r, m, correct = 0;
string capitals[50] =
{"Montgomery", "Juneau", "Phoenix", "Little Rock", "Sacramento", "Denver", "Hartford", "Dover", "Tallahassee", "Atlanta", "Honolulu", "Boise", "Springfield", "Indianapolis", "Des Moines", "Topeka", "Frankfort", "Baton Rouge", "Augusta", "Annapolis", "Boston", "Lansing", "St. Paul", "Jackson", "Jefferson City", "Helena", "Lincoln", "Carson City", "Concord", "Trenton", "Santa Fe", "Albany", "Raleigh", "Bismarck", "Columbus", "Oklahoma City", "Salem", "Harrisburg", "Providence", "Columbia", "Pierre", "Nashville", "Austin", "Salt Lake City", "Montpelier", "Richmond", "Olympia", "Charleston", "Madison", "Cheyenne"};
string states[50] = {"Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Carolina","North Dakota","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"};
//title
cout << "***************************************************************\n";
cout << "* *\n";
cout << "* United States Capitals Quiz *\n";
cout << "* *\n";
cout << "***************************************************************\n\n";
for (int i = 0; i < 15; i++){
//Picking A Random State
r = rand() % 50;
//Checking if State is a Repeat
if (states[r] != "-1") {
cout << "What is the capital of " << states[r] << "? ";
//Picking Correct Answer Choice and Respective Layout
m = rand() % 4;
if (m == 0) {
cout << "\nA: " << capitals[r] << endl;
cout << "B: " << capitals[rand()%50] << endl;
cout << "C: " << capitals[rand()%50] << endl;
cout << "D: " << capitals[rand()%50] << endl;
}
if (m == 1) {
cout << "\nA: " << capitals[rand()%50] << endl;
cout << "B: " << capitals[r] << endl;
cout << "C: " << capitals[rand()%50] << endl;
cout << "D: " << capitals[rand()%50] << endl;
}
if (m == 2) {
cout << "\nA: " << capitals[rand()%50] << endl;
cout << "B: " << capitals[rand()%50] << endl;
cout << "C: " << capitals[r] << endl;
cout << "D: " << capitals[rand()%50] << endl;
}
if (m == 3) {
cout << "\nA: " << capitals[rand()%50] << endl;
cout << "B: " << capitals[rand()%50] << endl;
cout << "C: " << capitals[rand()%50] << endl;
cout << "D: " << capitals[r] << endl;
}
//Recieving Answer
cout << "Answer: ";
cin >> answer;
//Converting Letter to Number
if (answer == 'A' || answer == 'a') answer = 0; if (answer == 'B' || answer == 'b') answer = 1;
if (answer == 'C' || answer == 'c') answer = 2; if (answer == 'D' || answer == 'd') answer = 3;
//Comparing Answer to Correct Answer
if (m == answer) {
cout << "Correct!" << endl << endl;
correct++;
}else{
cout << "Incorrect! The correct answer was " << capitals[r] << "! \n\n";
}
//Removing State from Array
states[r] = "-1";
}else{
//If State was a Repeat, generate another State
i--;
}
}
//Printing Results
cout << "Number Correct: " << correct << "/15 or " << ((correct/15.00)*100) << "%!\n";
return 0;
}
The code works, almost. The problem is that answers are sometimes being repeated, such as in the scenario:
What is the capital of Wisconsin?
A. Madison
B. Frankfort
C. Jackson
D. Madison
Only A or D is the "correct" answer despite both having the same text (altough I'd rather make it impossible for the answers to repeat). I also would like to know if there is a more efficient way to create the layout of multiple choice questions. Thanks in advance!
-Ayush
Given that there are 50 values you want to draw from at random, without repetition, simply create an array or vector containing those values, shuffle it, and then access the elements of the shuffled array in order.
In C++11, this is easy using algorithms std::iota() and std::random_shuffle() from <algorithm>.
int value[50];
std::iota(std::begin(value), std::end(value), 0); // populate array with values 0 to 49
std::random_shuffle(std::begin(value), std::end(value));
Then in your outer loop, instead of r = rand()%50 use r=value[i].
std::begin() and std::end() are in standard header <iterator>.
The same idea can be used before C++11, but the method is a little different (C++11 didn't support std::begin(), std::end() or std::iota(), but equivalents are easy enough to implement).
Instead of value being an array, I'd create it as an std::vector<int>, also with 50 elements. I've illustrated above using an array, since you seem to be defaulting to using an array.
That's a pretty obvious thing to happen. An easy solution would be to make an array to hold the options already displayed. Use a while loop to add unique options to the array.You could check whether there is any repetition in the array using another function. Then, display capitals[r] along with three other options from the array.
bool noRepeat(int arr[], int o){
for(int i=0; i<3; i++){
if(arr[i] == o)
return false;
}
return true;
}
int main(){
...
//picking correct answer and determining layout
int m = rand()%4, n=0, y, options[3];
if (m == 0) {
while(n<3){
y = rand()%50;
if(noRepeat(options, y) && capitals[y]!=capitals[r])
options[n++] = y;
}
//display according to layout
cout << "\nA: " << capitals[r] << endl;
cout << "B: " << capitals[options[0]] << endl;
cout << "C: " << capitals[options[1]] << endl;
cout << "D: " << capitals[options[2]] << endl;
}
//do the same for the rest
...
}
Just like #Isaiah said you can use a while loop to test for the index generated to not be same your correct answer.
Something like :
int index = rand() % 50;
while(index == r)
{
index = rand() % 50;
}
cout << "B: " << capitals[index] << endl;
NOTE: this still can produce repeats of "incorrect answers", but i guess you get the point to avoid the repeats produced by rand. And obviously this is code is just to correct the repeats of corrects answer, you should be using rand at all as mentioned in comments by others.
Your problem is to pick three random capitals without repeats. So here's some pseudo code.
Put all capitals, except the true answer into a vector
Generate a random index into this vector
Use the capital at that index, and erase the capital from the vector
Repeat Steps 2 and 3 for the second and third random capitals. Note the random index should allow for the reduced vector size on each iteration.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm using C++, and I have increments and decrements down solidly, but I have one equation where I have to decrement theChar equation, or the one with int var by -2, and I do not know the code for it.
Please formulate your question better. What do you mean with
I have one equation where I have to decrement "theChar" equation, or
the one with "int var" by -2
Do you mean:
char x = 'a';
x = x + 3; //now x is 'd'
int var = 10;
var -= 2; //equal to var = var -2;
The equations are not equations in a math sense of equation.
The = sign tells the computer to store whats on the right side into the variable that is on the left side.
int a;
a = 5;
this stored the 5 into a once.
int a, b;
a = 5;
b = a;
a = 6;
b is still 5 because when it was stored it copied from a. When a changed b was not recalculated but stayed as it was.
int a;
a = 5;
a = a - 2;
a is now beeing decremented by 2 since a was set to 5 when the right side ( a - 2 ) is calculated it is calculated to be 3. When that is done it gets written to the left side which happens to be a so at this point a is overwritten with 3;
char c = 'B';
c = c - 1;
c has a value of 'A' at the end of this code. There is some behind the scenes magic going on.
Characters are also numbers. So what really happens when i store 'B' into the variable the computer actually stores 66. You can read up on that here. When i decrement by one the value is decremented from 66 to 65. The character with the number 65 happens to be 'A'.
I read in the comments that you have trouble putting it all into a program.
I went ahead and wrote a code snippet for you.
#include <iostream>
using namespace std;
int main()
{
int a, b;
char c;
//cout is like a friend that you give something to put on the console
// << means give this to cout
cout << "Hello World!" << endl; //endl is a new line character
cout << endl << "Setting a, b" << endl;
a = 5;
b = a;
cout << "Value of a is " << a << ". " << "Value of b is " << b << "." << endl;
cout << endl << "Changing a" << endl;
a = 3;
cout << "Value of a is " << a << ". " << "Value of b is " << b << "." << endl;
cout << endl << "Adding to a" << endl;
a = a + 3;
cout << "Value of a is " << a << ". " << "Value of b is " << b << "." << endl;
cout << endl << "Playing around with characters" << endl;
c = 'B';
cout << "Character c is " << c << ". " << "Number stored for c is actually " << (int)c << "." << endl;
c = c + 1;
cout << "Character c is " << c << ". " << "Number stored for c is actually " << (int)c << "." << endl;
c = 70;
cout << "Character c is " << c << ". " << "Number stored for c is actually " << (int)c << "." << endl;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm making a USD to MXN converter and I want to have it work both ways. The if statement works (tryed cout << "test"; and it worked) but it wont work when I replace it with the goto statement.
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int user;
int u, m;
cout << "US/MXN Converter" << endl;
cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
cout << endl;
cout << "What Way to convert" << endl;
cout << "[1] US to MXN" << endl;
cout << "[2] MXN to US" << endl;
cout << "Selection: ";
cin >> user;
if (user == 1)
{
goto USTMXN;
}
else
{
goto MXNTUS;
}
USTMXN:
cout << "Enter the amount of US Dollars to Convert" << endl;
cout << "Amount: ";
cin >> u;
m = u * 12.99;
cout << endl;
cout << "MXN Pesos: " << m << endl;
goto END;
MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;
END:
system("PAUSE");
return EXIT_SUCCESS;
}
One of the most fundamental things we have to do as programmers is to learn to break problems into smaller problems. You are actually running into a whole series of problems.
I'm going to show you how to solve your problem. You may want to book mark this answer, because I'm pre-empting some problems you're going to run into a few steps down the line and preparing you - if you pay attention - to solve them on your own ;)
Let's start by stripping down your code.
Live demo here: http://ideone.com/aUCtmM
#include <iostream>
int main()
{
std::cout << "Enter a number: ";
int i;
std::cin >> i;
std::cout << "Enter a second number: ";
int j;
std::cin >> j;
std::cout << "i = '" << i << "', j = '" << j << "'\n";
}
What are we checking here? We're checking that we can ask the user two questions. That works fine.
Next is your use of goto, which I strongly recommend you do not use. It would be better to use a function. I'll demonstrate with your goto case here first:
#include <iostream>
int main()
{
int choice;
std::cout << "Enter choice 1 or 2: ";
std::cin >> choice;
if ( choice == 1 )
goto CHOSE1;
else if ( choice == 2 )
goto CHOSE2;
else {
std::cout << "It was a simple enough question!\n";
goto END;
}
CHOSE1:
std::cout << "Chose 1\n";
goto END;
CHOSE2:
std::cout << "Chose 2\n";
goto END;
END:
std::cout << "Here we are at end\n";
}
live demo: http://ideone.com/1ElcV8
So goto isn't the problem.
That leaves your use of variables. You've really mixed things up nastily by having a second set of variables (mm, uu). Not only do you not need to have these, you're doing something very naughty in that these variables only exist inside one scope and not the other. You can "get away" with this but it will come back to haunt you later on.
The difference in your two main streams of code is the variable names. The second conversion case looks like this:
MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;
The problem here is that you have - accidentally - used the variable "m" in your output. It's what we call uninitialized.
cout << "US Dollars: " << m << endl;
That m in the middle should be mm.
Your compiler should actually be warning you about this. If it's not, and you're just setting out learning, you should figure out how to increase the compiler warning level.
It would be better to make a function to do the conversions; you could make one function for each direction, but I've made a function that handles both cases:
#include <iostream>
static const double US_TO_MXN = 12.99;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
std::cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
std::cin >> original;
std::cout << to << ": " << (original * exchange) << '\n';
}
int main() // this is valid since C++2003
{
std::cout << "US/MXN Converter\n"
"1 US = " << US_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
int choice = 0;
// Here's a better demonstration of goto
GET_CHOICE:
std::cout << "Which conversion do you want to perform?\n"
"[1] US to MXN\n"
"[2] MXN to US\n"
"Selection: ";
std::cin >> choice;
if (choice == 1)
convert("US Dollars", "Pesos", US_TO_MXN);
else if (choice == 2)
convert("Pesos", "US Dollars", 1 / US_TO_MXN);
else {
std::cerr << "Invalid choice. Please try again.\n";
goto GET_CHOICE;
}
// this also serves to demonstrate that goto is bad because
// it's not obvious from the above that you have a loop.
}
ideone live demo: http://ideone.com/qwpRtQ
With this, we could go on to clean things up a whole bunch and extend it:
#include <iostream>
using std::cin;
using std::cout;
static const double USD_TO_MXN = 12.99;
static const double GBP_TO_MXN = 22.03;
static const char DATA_DATE[] = "6/12/2014";
void convert(const char* from, const char* to, double exchange)
{
cout << "Enter the number of " << from << " to convert to " << to << ".\n"
"Amount: ";
int original;
cin >> original;
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
}
int main() // this is valid since C++2003
{
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
for ( ; ; ) { // continuous loop
cout << "Which conversion do you want to perform?\n"
"[1] USD to MXN\n"
"[2] MXN to USD\n"
"[3] GBP to MXN\n"
"[4] MXN to GBP\n"
"[0] Quit\n"
"Selection: ";
int choice = -1;
cin >> choice;
cout << '\n';
switch (choice) {
case 0:
return 0; // return from main
case 1:
convert("US Dollars", "Pesos", USD_TO_MXN);
break;
case 2:
convert("Pesos", "US Dollars", 1 / USD_TO_MXN);
break;
case 3:
convert("British Pounds", "Pesos", GBP_TO_MXN);
break;
case 4:
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN);
break;
default:
cout << "Invalid selection. Try again.\n";
}
}
}
http://ideone.com/iCXrpU
There is a lot more room for improvement with this, but I hope it helps you on your way.
---- EDIT ----
A late tip: It appears you're using visual studio, based on the system("PAUSE"). Instead of having to add to your code, just use Debug -> Start Without Debugging or press Ctrl-F5. It'll do the pause for you automatically :)
---- EDIT 2 ----
Some "how did you do that" points.
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
I very carefully didn't do the using namespace std;, when you start using more C++ that directive will become the bane of your existence. It's best not to get used to it, and only let yourself start using it later on when you're a lot more comfortable with C++ programming and more importantly debugging odd compile errors.
But by adding using std::cout and using std::cin I saved myself a lot of typing without creating a minefield of function/variable names that I have to avoid.,
What does the line do then:
cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
The '\n' is a single character, a carriage return. It's more efficient to do this than std::endl because std::endl has to go poke the output system and force a write; it's not just the end-of-line character, it actually terminates the line, if you will.
int(original * exchange)
This is a C++ feature that confuses C programmers. I'm actually creating a "temporary" integer with the result of original * exchange as parameters.
int i = 0;
int i(0);
both are equivalent, and some programmers suggest it is better to get into the habit of using the second mechanism so that you understand what happens when you later run into something called the "most vexing parse" :)
convert("Pesos", "British Pounds", 1 / GBP_TO_MXN)
The 1 / x "invert"s the value.
cout << "Foreign Currency Converter\n"
"1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
"\n";
This is likely to be confusing. I'm mixing metaphors with this and I'm a little ashamed of it, but it reads nicely. Again, employ the concept of breaking problems up into smaller problems.
cout << "Hello " "world" << '\n';
(note: "\n" and '\n' are different: "\n" is actually a string whereas '\n' is literally just the carriage return character)
This would print
Hello world
When C++ sees two string literals separated by whitespace (or comments) like this, it concatenates them, so it actually passes "Hello world" to cout.
So you could rewrite this chunk of code as
cout << "Foreign Currency Converter\n1 USD = ";
cout << USD_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n1 GBP = ";
cout << GBP_TO_MXN;
cout << " MXN (";
cout << DATA_DATE;
cout << ")\n\n";
The << is what we call "semantic sugar". When you write
cout << i;
the compiler is translating this into
cout.operator<<(i);
This odd-looking function call returns cout. So when you write
cout << i << j;
it's actually translating it to
(cout.operator<<(i)).operator<<(j);
the expression in parenthesis (cout.operator<<(i)) returns cout, so it becomes
cout.operator<<(i); // get cout back to use on next line
cout.operator<<(j);
Main's fingerprint
int main()
int main(int argc, const char* argv[])
Both are legal. The first is perfectly acceptable C or C++. The second is only useful when you plan to capture "command line arguments".
Lastly, in main
return 0;
Remember that main is specified as returning int. The C and C++ standards make a special case for main that say its the only function where it's not an error not to return anything, in which case the program's "exit code" could be anything.
Usually its best to return something. In C and C++ "0" is considered "false" while anything else (anything that is not-zero) is "true". So C and C++ programs have a convention of returning an error code of 0 (false, no error) to indicate the program was successful or exited without problems, or anything else to indicate (e.g. 1, 2 ... 255) as an error.
Using a "return" from main will end the program.
Try to change youre code for sth like this. Using goto label is not recommended.
Main idea of switch statement :
int option;
cin >> option
switch(option)
{
case 1: // executed if option == 1
{
... code to be executed ...
break;
}
case 99: //executed id option == 99
{
... code to be executed
break;
}
default: // if non of above value was passed to option
{
// ...code...
break;
}
}
Its only example.
int main(int argc, char *argv[])
{
int user;
int u, m;
cout << "US/MXN Converter" << endl;
cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
cout << endl;
cout << "What Way to convert" << endl;
cout << "[1] US to MXN" << endl;
cout << "[2] MXN to US" << endl;
cout << "Selection: ";
cin >> user;
switch(user )
{
case 1 :
{
//USTMXN:
cout << "Enter the amount of US Dollars to Convert" << endl;
cout << "Amount: ";
cin >> u;
m = u * 12.99;
cout << endl;
cout << "MXN Pesos: " << m << endl;
break;
}
}
default :
{
//MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
break;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
What is the problem with the last two statements in the code?
#include <iostream>
using namespace std;
int main()
{
cout << "2 + 4 = " << 2 + 4 << endl;
cout << "2 * 4 = " << 2 * 4 << endl;
cout << "2 | 4 = " << 2 | 4 << endl;
cout << "2 & 4 = " << 2 & 4 << endl;
What should I do to fix this?
What is the problem with the last two statements in the code?
Operator precedence. | and & have lower precedence than <<, so cout << "2 & 4 = " << 2 & 4 << endl; gets parsed as (cout << "2 & 4 = " << 2) & (4 << endl;).
What should I do to fix this?
Put parens around 2 | 4 and 2 & 4.
Put the expression in parentheses. The << operator is taking precedence over the bitwise operators.
#include <iostream>
using namespace std;
int main()
{
cout << "2 + 4 = " << 2 + 4 << endl;
cout << "2 * 4 = " << 2 * 4 << endl;
cout << "2 | 4 = " << (2 | 4) << endl;
cout << "2 & 4 = " << (2 & 4) << endl;
return 0;
}