Win32 Console Application won't run in VS2012 Pro - c++

I am teaching myself C++ with Prata's C++ Primer Plus and am having an issue. I don't get any errors in VS2012 Pro and the program compiles successfully but gives me an unhandled exception (Unhandled exception at 0x76ED016E (ntdll.dll) in Prata 2.5.exe: 0x00000000: The operation completed successfully.) when I try to enter C or F as my initial option and I am not sure where I have gone wrong. The exercise only asked me to create a simple program that converted Fahrenheit to Celsius, but I thought that I would find something like this useful as I often use online sources to do this conversion. If I had my own program, I wouldn't have to worry and can expand it to a non CLI version and more conversion options (ie. yards to metres etc). Any help would be appreciated.
#include "stdafx.h"
#include <iostream>
// Function Prototypes
double convertToF(double);
double convertToC(double);
int main()
{
using namespace std;
char* convertChoice = "a"; // Initializing because the compiler complained. Used to choose between celsius and fahrenheit.
int choiceNumber; // Had issues using the char with switch so created this.
double tempNumber; // The actual temperature the user wishes to convert.
cout << "Do you wish to convert to [C]elcius or [F]ahrenheit?";
cin >> convertChoice;
// IF() compares convertChoice to see if the user selected C for Celsius or F for fahrenheit. Some error catching by using the ELSE. No converting char to lower though in case user enters letter in CAPS.
if (convertChoice == "c")
{
cout << "You chose Celsius. Please enter a temperature in Fahreinheit: " << endl;
cin >> tempNumber;
choiceNumber = 1;
}
else if (convertChoice == "f")
{
cout << "You chose Fahrenheit Please enter a temperature in Celsius: " << endl;
cin >> tempNumber;
choiceNumber = 2;
}
else
{
cout << "You did not choose a valid option." << endl;
}
// SWITCH() grabs the int (choiceNumber) from the IF(), goes through the function and outputs the result. Ugly way of doing it, but trying to make it work before I make it pretty.
switch (choiceNumber)
{
case 1:
double convertedFTemp;
convertedFTemp = convertToC(tempNumber);
cout << convertedFTemp << endl;
break;
case 2:
double convertedCTemp;
convertedCTemp = convertToF(tempNumber);
cout << convertedCTemp << endl;
break;
default:
cout << "You did not choose a valid option." << endl;
break;
}
// To make sure the window doesn't close before viewing the converted temp.
cin.get();
return 0;
}
// Function Definitions
double convertToF(double x)
{
double y;
y = 1.8 * x + 32.0;
return y;
}
double convertToC(double x)
{
double y;
y = x - 32 / 1.8;
return y;
}
I also don't know if I have everything right. ie. The formula in the functions as well as the order of the switch. Please don't correct that, I'll figure that out for myself once the damn thing compiles. :)

Please refer to the rule of thumb in the comments. You are using a char* without enough knowledge of the details to use it properly. Use std::string, it will do exactly what you need.
For future reference: With a char*
you need to allocate memory
you need to use strcmp to compare
you need to watch the length yourself
you need to deallocate the memory
That's a lot for starters. Use std::string.
string convertChoice = "a";
Don't forget to
#include <string>

Related

Why i'm getting overflow?

I'm very new to c++ and still in the process of learning it.
I've been assigned to create a simple bank simulator and just stumble upon a problem i can't seem to figure out for some reason.
Whenever i try to check the balance it shows me some numbers and letters and my first thought was either it showed the memory adress or a overflow.
I could deposit something first and it will be added to the balance variable and shows up in the program aswell without some awkward numbers and letters. My goal is to make sure that the balance is always showing a 0 until the user deposit or withdraw from it.
I somehow managed to fix this by using float instead of double, I'm not really sure why it worked at this point since I'm way to tired to even think about it, but I would rather use double since this program might use more data.
If anything seems unclear of what I'm trying to say I'll try and answer your question as soon as I can. I also add a image here to show you what I'm talking about.
#include <iostream>
using namespace std;
int main()
{
while(true){
cout << "[D]eposit\n";
cout << "[W]ithdrawal\n";
cout << "[B]alance\n";
cout << "[I]nterest payment\n";
cout << "[E]xit\n";
char menu;
double balance, deposit, withdraw;
cin >> menu;
switch(menu)
{
case'D':
cout << "[DEPOSIT]\n" << "Deposit: ";
cin >> deposit;
balance += deposit;
continue;
case'W':
cout <<"[WITHDRAWAL]\n" << "Withdraw: ";
cin >> withdraw;
balance -= withdraw;
continue;
case'B':
cout << "[BALANCE]\n" << "Amount: " << balance;
continue;
case'I':
cout << "[INTEREST PAYMENT]\n";
continue;
case 'E':
cout << "Program is closing...";
break;
default:
cout << "Please use uppercase letters";
continue;
}
break;
}
return 0;
}
Balance isn't initialized, so when you add / substract an amount, the result is odd due to the random initial value of balance.
Well the main reason for getting the gibberish data is because your balance variable is uninitialized, and accessing it is undefined behaviour.
You can fix it by doing this:
double balance = 0;
double deposit, withdraw;
Also, your program won't work as expected because you declare the balance variable inside the while loop. Just declaring the variables outside the loop will make it work as expected.
double balance = 0;
double deposit, withdraw;
while(true){
...
}

I can't seem to get his c++ script to not return a 0 at one point

so when I run this code, the print_conclusion function (I'm assuming) seems to output an unwanted zero. Can someone please tell me how to not get this zero to show up by suggesting improvements to my code? Thanks
I'm just going to repeat my question so this isn't "mostly code"
so when I run this code, the print_conclusion function (I'm assuming) seems to output an unwanted zero. Can someone please tell me how to not get this zero to show up by suggesting improvements to my code? Thanks
I'm just going to repeat my question so this isn't "mostly code"
so when I run this code, the print_conclusion function (I'm assuming) seems to output an unwanted zero. Can someone please tell me how to not get this zero to show up by suggesting improvements to my code? Thanks
I'm just going to repeat my question so this isn't "mostly code"
so when I run this code, the print_conclusion function (I'm assuming) seems to output an unwanted zero. Can someone please tell me how to not get this zero to show up by suggesting improvements to my code? Thanks
[code]
//#include<stdio.h>
#include"stdafx.h"
#include<iostream>
#include<string>
//#include <cmath>
using namespace std;
double depth, temperatureCelsius, tempCelToFah;
char usersInput;
string print_introduction() {
// prints out information to tell the user what this program does.
//cout << "This program calculates the temperature of the earth when given a depth in kilometers" << endl;
return "This program calculates the temperature of the earth when given a depth in kilometers\n";
}
double celsius_at_depth(double depth) {
// computes and returns the celsius temperature at a depth measured in kilometers.
return temperatureCelsius = 10 * depth + 20;
}
double celsius_to_fahrenheit(double celsius) {
// converts a Celsius temperature celsius to Fahrenheit.
return tempCelToFah = 1.8*celsius + 32;
}
double print_conclusion(double depth) {
//return
// display the conclusion that what is the temperature in both Celsius and Fahrenheit at depth of the earth
//does all necessary calculations
celsius_at_depth(depth);
celsius_to_fahrenheit(temperatureCelsius);
cout << "The temperature at depth " << depth << " kilometers. In Celsius the temperature is " << temperatureCelsius << "\n... in Fahrenheit it is " << tempCelToFah << " degrees.\n";
return 0;
//I'm assuming the extra zero in my output comes from this return but I cannot figure out how to get rid of it!!!
}
int main()
{
//1. print introduction by calling print_introduction() function
cout << print_introduction() << endl;
//2. ask user to enter the depth
cout << "Please enter the depth in kilometers" << endl;
//3. get user’s input
cin >> depth;
//4. print out the conclusion by calling print_conclusion function
//cout << print_conclusion(depth); //did not work left zero
cout << print_conclusion(depth) << endl;
//5. ask user if he/she wants to continue
cout << "Would you like to continue? (y/n)?";
//6. get user’s input
cin >> usersInput;
//7. repeat step 2 to step 6 if user picks ‘Y’ or ‘y’
if (usersInput == 'Y' || usersInput == 'y')
{
main();
}
else {
//Stop program
return 0;
}
}
[/code]
Cout will print the output of the function.
Hence, you shouldn't print the output of your function to avoid the 'extra zero'
print_conclusion(depth);

cin not accepting user input in C++

I'm a beginner in programming, and I'm trying to make a program that calculated how much radiation you've been exposed to throughout your life. For some reason, the 'cin' in my xray function doesn't accept user input, and just exits with code 0.
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
#include <string>
#include <sstream>
using namespace std;
bool nearpowerplant;
int XRay; // the amount of times you got an x-ray
double tRads = 0; // your total dose of radiation in your lifetime, measured in mSv (millisievert)
int age;
//the sleep function
void sleep() {
Sleep(1000); // 1000 miliseconds = 1 second
}
/*
>system("CLS")< for clear the console
*/
//introduction and pretty much the menu
void intro() {
cout << "Welcome to the Radiation Level Calculator" << endl;
sleep();
cout << "Conceptualized and created by Anatoly Zavyalov" << endl;
sleep();
cout << "Press the ENTER key to begin." << endl;
cin.get();
}
//introduction to general questions
void genintro() {
// intro to the medical
system("CLS");
sleep();
cout << "Let's begin with general questions." << endl;
sleep();
cout << "Press the ENTER key to continue." << endl;
cin.get();
}
//medical questions
void Age() {
//age
system("CLS");
cout << "How old are you?\n" << endl;
sleep();
cin >> age;
if (age <= 0) {
cout << "Your age can't be less or equal to 0." << endl;
Age();
}
else {
tRads += (age * 2);
sleep();
cout << tRads << endl;
}
}
//live close to powerplant?
void powerplant() {
system("CLS");
cout << "Do you live within 75 kilometers of a nuclear powerplant?" << endl;
sleep();
cout << "If yes, type YES. If no, type NO." << endl;
cin >> nearpowerplant;
if (nearpowerplant = "YES") {
tRads += (age * 0.01);
}
else {}
sleep();
cout << tRads << endl;
}
void xray() {
system("CLS");
cout << "How many times have you had an x-ray?\n" << endl;
sleep();
cin >> XRay;
if (XRay < 0) {
cout << "You can't have an x-ray a negative amount of times." << endl;
}
else {
tRads += (XRay * 3.1);
}
sleep();
cout << tRads << endl;
}
//main function, put all of the loops into here
int main() {
intro(); // the introduction
genintro(); // medical intro
Age(); // asks for age
powerplant(); // asks if lives close to powerplant
xray(); // asks for x-ray
return 0;
}
EDIT: I have edited the post to include the whole code. By the way, I am using Visual Studio Community 2017.
bool nearpowerplant;
nearpowerplant is a bool. It is true or false. That is it. It's worth noting that there is no reason for this variable to be globally accessible and consuming storage for the entire run of the program. It is used twice in the program, both times in the same function. It should be an Automatic variable scoped by the function that uses it.
cout << "If yes, type YES. If no, type NO." << endl;
cin >> nearpowerplant;
Reading "YES" or "NO" into a variable of type bool fails. cin cannot convert the string input into a boolean value and cin stops accepting input until the error is cleared. It's also a good idea to remove the garbage input that caused cin to fail or guess what? cin's just going to fail again. There are hundreds of SO questions on how to handle this, so I'm just going to drop keywords here: clear and ignore.
Takeaways: Make sure the data entry matches the type of the data being entered into and test the stream after every read to make sure the read succeeded.
eg:
if (cin >> nearpowerplant)
{
// do stuff
}
else
{
// clean up
}
This solves OP's visible error, but since it is heavily entwined with the next bug they are likely to find, we might as well cover it as well.
if (nearpowerplant = "YES") {
tRads += (age * 0.01);
}
else {}
if (nearpowerplant = "YES") { uses = (assignment) where it should use == (comparison). C++ is unforgiving here because this will compile. What it really did was takes the address of the string literal "YES", test that it's not null, and set nearpowerplant to the result. Since the address of the string literal is never going to be NULL, the result is always true, and when the if tests the result, the if will always enter.
Eg: http://ideone.com/4QL2jn
So what we need is something more like
cout << "If yes, type YES. If no, type NO." << endl;
string temp;
cin >> temp;
if (temp == "YES") {
tRads += (age * 0.01);
}
else {}
Note this will skip if the user inputs "yes", "y", "Yes" or anything other than exactly "YES". How you deal with this is up to you, but std::tolower and std::transform may help somewhat.
I think with sleep() comes undefined behavior, you should test it without, the os handles user-input and you do not have to care about the user typing in. endl flushes cout, so the text is directly shown.
Edit:
Maybe system("CLS") or sleep produces a silent error.

Why does this cause in infinite loop with chars but not doubles?

I feel like im doing something really silly wrong. I just want the program to tell the user when they are entering non-doubles, and continue to loop back to the cin where you enter a value.
I want the user to input any number. Then essential do this trivial math and repeat. Its working fine in that regard, the problem comes when some unexpected input like a char gets entered. Then the input somehow sends it into a loop where it loops the math problem, instead of just telling the user that they must type a number and looping back to cin type in a new number.
#include <iostream>
#include <cstdlib>
using std::cout; using std::cin; using std::endl;
long double domath(long double i)
{
cout << i << "/" << 2 << "=" << i/2 << endl;
cout << i/2 << "*" << 10 << "=" << (i/2)*10 << endl << endl;
cout << 5 << "*" << i << "=" << 5*i << "\n\n";
return 0;
}
int main()
{
long double in = 0;
while(true)
{
cin >> in;
if (cin.fail()) {
in = char(int(in));
}
domath(in);
}
system("pause>nul");
return 0;
}
You don't clear the cin in case of fail, and it infinitely tries to parse wrong input to double, failing every time. You need to clear the buffer in case of error:
if (cin.fail()) {
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
in = char(int(in));
}
Also, can't understand what you're trying to achieve with
in = char(int(in));
in is a long double variable and will hold the last value you assigned to it, no need to "convert" it to do math.
Couldn't you try doing something like this?
int x;
if(std::cin >> x)
doSomethingCool(x);
else
std::cout << "Error, not a valid integer!" << std::endl;
Exit your loop on bad input.
I think this just feels more natural/looks cleaner than clearing the buffer and all the other jazz. Just my opinion.
if (cin >> x) - Why can you use that condition?
edit: Bul's answer is still a good one though.

C++ cin positive integers only

This is my first time on Stackoverflow.
I was making a program to find out MPG for a car. I was wondering how can I make the cin statement only accept positive integers only? and also, if you do enter a invalid input, can you reset it? I am not sure if that makes sense. I didn't have to do this for class. I was just curious on how to do it. Here is the code.
#include <iostream>
using namespace std;
int main()
{
double tank, miles, mpg;
cout << "Hello. This is a program that calculates the MPG ( Miles Per Gallon) for your\n" ;
cout << "vehicle\n" << endl;
cout << "Please enter how many gallons your vehicle can hold\n" << endl;
cin >> tank;
cout << endl;
cout << "Please enter how many miles that have been driven on a full tank\n" <<endl;
cin >> miles;
cout << endl;
mpg = (miles)/(tank);
cout << "Your vehicle recieves " << mpg << " miles per gallon\n" << endl;
system ("pause");
return 0;
}
iostreams are not a toolkit for building a complex UI. Unless you want to write your own rather complex stream to wrap the usual stream, there is no way you are going to get it to either (a) only accept positive integers or (b) interact politely with a user who types in something else.
You should just read lines from cin, and print your own error prompts and such after you look at what you get.
cout << "Hello. This is a program that calculates the MPG ( Miles Per Gallon) for your\n" ;
cout << "vehicle\n" << endl;
do
{
cout << "Please enter how many gallons your vehicle can hold\n" << endl;
cin >> tank;
cout << endl;
} while (tank <= 0 && ((int)tank != tank));
do
{
cout << "Please enter how many miles that have been driven on a full tank\n" <<endl;
cin >> miles;
cout << endl;
} while (miles <= 0 && ((int)miles != miles));
If you do this after running the statements it will rerun them if the answer is 0 or lower or is not an integer. If you make the variables ints instead of doubles then you can remove the "&& ((int)miles == miles)" part of the while statement.
Still, there are a couple of standard ways to do it in a command line environment.
You could trap the cin statement in a loop that doesn't release until a valid input has been entered. This is the "standard" way to validate CLI input, not just signed numbers.
do
{
cout << "\nPlease enter...";
cin >> tank;
}
while (tank < 0)
The condition in the while statement is the place to validate the data. You can also make an if statement to explain why the input is invalid.
The other way is to simply force the value to be positive, by simply going tank = fabs(tank);, which takes the absolute value (i.e. positive) of the tank variable.
So this is my code for an infinite loop
1: So main will call the "Get_number()" function
2: Get number will accept an int from the user
3(A): If int is greater than 0, go into loop
3(B): Else, display to user "Invalid Input" and then call the function
"Get_number()" again creating an infinite loop until the user
enters a value greater than 0
#include <iostream> // Access the input output stream library
#include <fstream> // Access to the fstream library (used to read and write to files)
#include <chrono> // Needed to access "std::chrono_literals"
#include <thread> // Needed to access "namespace std::this_thread"
using std::fstream; // this will allow us to use the fstream (we'll be able to read and write to files)
using std::ios; // needed for iostream (used to be able to tell fstream to read and/or write to a file and that it's reading/writing a binary file)
using std::cout; // need this statment to access cout (to display info to user)
using std::cin; // need this statment to access cin (to gather info from user)
using std::endl; // need this statment to access endl (will end the line)
using namespace std::this_thread; // This will allow me to use "Sleep_For" or "Sleep_Until"
using namespace std::chrono_literals; // This will allow the use of measurements of time such as ns, us, s, h, etc.
//Prototypes***************************************************************************************************
void shellSort(int read[], int readLength); //Making Prototype (Declaring our function) so that compiler knows not to worry about it
void Get_number();
void Write_to_file(int user_input_of_how_many_random_numbers_to_generate); //Making Prototype (Declaring our function) so that compiler knows not to worry about it
void Read_from_file(int user_input_of_how_many_random_numbers_to_generate);//Making Prototype (Declaring our function) so that compiler knows not to worry about it
//*************************************************************************************************************
void main()
{
Get_number();
system("pause>>void"); // will let the console pause untill user presses any button to continue
}
/**************************************************************************************************************
* Purpose: This function will gather a positive integer from the user and use it to generate that many
* random numbers!
*
* Precondition: None
*
*
* Postcondition:
* Would've gathered the number of random numbers the user wanted to generate and then gone into the
* Write_to_file and Read_from_file function
*
**************************************************************************************************************/
void Get_number()
{
int user_input_of_how_many_random_numbers_to_generate = 0; //make variable that will accept the int value the user wants to generate random numbers
cout << "Please Enter A Number Greater Than Zero:" << endl; // displays to user to enter a number greater than zero
cin >> user_input_of_how_many_random_numbers_to_generate; // will accept the value the user inputted and place it in the "user_input_of_how_many_random_numbers_to_generate" variable
system("cls"); // Will clear the screen
if (user_input_of_how_many_random_numbers_to_generate > 0) // if user input is greater than zero, enter this
{
Write_to_file(user_input_of_how_many_random_numbers_to_generate); // will bring up the "Write_to_file" function
Read_from_file(user_input_of_how_many_random_numbers_to_generate); // will bring up the "Read_from_file" function
}
else // else enter this
{
cout << "invalid input!" << endl; // display to user "invalid input"
sleep_for(2s); // system will pause for 2 seconds allowing the user to read the message of "invalid input"
system("cls"); // console will be cleared
Get_number(); // Get_number function will be entered creating an infinate loop untill the user's input is valid!
}
}
Instead of
cin >> miles;
Try
while ( (cin >> miles) < 0 )
cout << "Please enter how many gallons your vehicle can hold\n" << endl;
That will repeat the question until the input is positive. You can do that for the rest of the questions too.
Note that input streams are not intended for input filtering. You have to provide your own logic for that.