Program crashes after it compiles - c++

I am writing a program for my C++ class and can't seem to figure out what the problem with is with my code. The code compiles but something causes the program to crash after line 16 that I just can't figure out.
#include <iostream>
// Declare Global variables and Prototyping
int const TAX = .07;
float inputStickerPrice();
int main()
{
float totalStickerPrice = 0.0, discount = 0.0, totalPrice = 0.0;
char* pass = "";
// Calculate the total sticker price
while (pass != "n")
{
totalStickerPrice += inputStickerPrice();
std::cout << "Would you like to enter another item? [y/n] ";
std::cin >> pass;
// Pass validation Loop
while (pass != "y" && pass != "n")
{
std::cout << "INVALID INPUT. Please enter y for yes or n for no. ";
std::cin >> pass;
} // End of Pass Loop
} // End of Sticker Price Loop
// Input Discount
while (!(discount >= 0.0 && discount <= 1))
{
std::cout << "Please enter the discount: ";
std::cin >> discount;
// Validate input
if (!(discount >= 0.0 && discount <= 1))
{
std::cout << "INVALID INPUT. Discount must be between 0.0 and 1.0. ";
} // End of validation
} // End of Discount Loop
totalPrice = totalStickerPrice * discount; // Apply Discount to total Sticker Price
std::cout << "The Subtotal is: " << totalPrice << std::endl;
totalPrice *= (1+TAX); // Apply Tax to Subtotal
std::cout << "The Cost after Tax is: " << totalPrice << std::endl;
std::cin.get();
return 0;
}
//**********************
// Input sub program *
//**********************
float inputStickerPrice()
{
using namespace std;
float sticker = 0.0;
cout << "Please input the sticker price of the item: ";
cin >> sticker;
// Validation Loop
while(!(sticker >= 0.0 && sticker <= 9999.99))
{
cout << "INVALID INPUT. Please input a value between 0 and 9999.99: ";
cin >> sticker;
} // End of Validation Loop
return sticker;
} // End of Input Function

char* pass = "";
Here you declared a pointer to a string literal, an array of characters which occupies a region of storage that you're not allowed to modify. Recent compilers that follow C++11 standard are supposed to produce an error for this line, because string literals are not implicitly convertible to char* anymore, but to const char* instead.
When you modify this memory in this line std::cin >> pass; your program has undefined behaviour and all bets are off. A crash is just one of possible outcomes.
Next, you can't compare strings like that:
pass != "y"
pass is a pointer and "y" decays to one. You're not comparing contents of string here, but pointer values that will never be the same.
Forget about pointers until you're ready to tackle them, use std::string class instead. Then comparing strings will be as easy as str1 == str2.

while (pass != "n")
pass is a pointer, so you should use *pass or pass[0] if you want to obain its value.
Besides look at #Borgleader comment
EDIT:
Change char pass*; into std::string pass; - it should fix the issue.

Related

How to print out a double value without losing first digit

When I run my code, it only prints the decimal parts of the double. On another page, I took a inputted double and printed out the double the way it was inputted.
But for my following code, it only prints out the decimals. For example, when I input 1.95 it only prints out 0.95. Why is it removing the first digit? I see nothing in my code that points to this.
I have already tried it in a more simple way and it worked. And I dont see any problems that would mess with the double in my code.
#include <iostream>
using namespace std;
int main()
{
double price;
char user_input;
do
{
cout << "Enter the purchase price (xx.xx) or `q' to quit: ";
cin >> user_input;
if (user_input == 'q')
{
return 0;
}
else
{
cin >> price;
int multiple = price * 100;
if (multiple % 5 == 0)
{
break;
}
else
{
cout << "Illegal price: Must be a non-negative multiple of 5 cents.\n" << endl;
}
}
} while (user_input != 'q');
cout << price << endl;
}
When I input 1.95, I get 0.95. But the output should be 1.95.
Problem covered in other answer: Reading for the 'q' removed the first character from the stream before it could be parsed into a double.
A solution: Read the double first. If the read fails, check to see if the input is a 'q'.
#include <iostream>
#include <limits>
using namespace std;
int main()
{
double price;
while (true)
{
cout << "Enter the purchase price (xx.xx) or `q' to quit: ";
if (cin >> price)
{
// use price
}
else // reading price failed. Find out why.
{
if (!cin.eof()) // didn't hit the end of the stream
{
// clear fail flag
cin.clear();
char user_input;
if (cin >> user_input && user_input == 'q') // test for q
{
break; // note: Not return. Cannot print price if the
// program returns
}
// Not a q or not readable. clean up whatever crap is still
// in the stream
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
{
// someone closed the stream. Not much you can do here but exit
cerr << "Stream closed or broken. Cannot continue.";
return -1;
}
}
}
cout << price << endl;// Undefined behaviour if price was never set.
}
Another reasonable alternative is to read all input as std::string. If the string is not "q", attempt to convert it to a double with std::stod or an std::istringstream.
When you type 1.95 in the command line, variable user_input gets assigned '1', and price gets assigned .95.

C++ Beginner Issue with moving b/w Functions

This is my first stackoverflow post, so apologies if it's poorly written or the like, but I am a super-beginner at C++ (As will likely be evident in the code) and am trying to complete the 100 Programming Challenge, I am only up to #3 - Temperature Converter.
My friend who has some programming experience in other languages is going to flick through it on my github tonight and see if he can't figure it out, but I thought I'd try stackoverflow as well.
I have no idea what specifically is causing the error so I'm going to have to post the entire code, but basically my issue is that it compiles fine, but when any input is entered it triggers cin.fail() and just loops around and jumps between functions almost seeming of it's own accord, however never entering CelstoFahr() or FahrtoCels().
Apologies again if my code is messy, if you have any suggestions please let me know, and feel free to critique my style as I'm always looking to improve. I can also link my github if necessary.
Code below:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <limits>
// Forward declaring the functions
double CinFailCheck(double cin_fail_check);
double CelstoFahr(double celsius_amount, double fahrenheit_amount);
double FahrtoCels(double celsius_amount, double fahrenheit_amount);
int UserSelectionValidate(int user_selection);
void pauseAtEnd();
bool UserRestart();
void menu();
// Initializing the functions, with user input validation, for Cels -> Fahr, Fahr -> Cels and User Selection
double CinFailCheck(double cin_fail_check)
{
while (std::cin.fail())
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "\nBad entry, no text allowed! Enter a Number: ";
std::cin >> cin_fail_check;
}
return cin_fail_check;
}
double CelstoFahr(double celsius_amount, double fahrenheit_amount)
{
// Declaring cin_fail_check to enable me to have the cin.fail() as a function
double cin_fail_check = 0;
// Perform cin.fail() on the users input then grab that input and clone it to celsius_amount
CinFailCheck(cin_fail_check);
celsius_amount = cin_fail_check;
std::cin.clear();
std::cin.ignore();
// Make conversion using the formula for C to F
fahrenheit_amount = (celsius_amount * 1.8) + 32;
return fahrenheit_amount;
}
double FahrtoCels(double celsius_amount, double fahrenheit_amount)
{
// Declaring cin_fail_check to enable me to have the cin.fail() as a function
double cin_fail_check = 0;
// Perform cin.fail() on the users input then grab that input and clone it to fahrenheit_amount
CinFailCheck(cin_fail_check);
fahrenheit_amount = cin_fail_check;
std::cin.clear();
std::cin.ignore();
// Make conversion using the formula for F to C
celsius_amount = (fahrenheit_amount - 32) * (5 / 9);
return celsius_amount;
}
int UserSelectionValidate(int user_selection)
{
// Declaring cin_fail_check to enable me to have the cin.fail() as a function
double cin_fail_check = 0;
// Perform cin.fail() on the users input then grab that input and clone it to user_selection
CinFailCheck(cin_fail_check);
user_selection = cin_fail_check;
std::cin.clear();
std::cin.ignore();
return user_selection;
}
// Function to enable a pause at the end to avoid the use of system("pause")
void pauseAtEnd()
{
std::cout << "\n\nPlease press Enter to exit . . .";
std::cin.sync();
std::cin.get();
}
// Restart function to avoid having to re-write it all each time
bool UserRestart()
{
bool CONVERTER_RUNNING = true;
bool BOOL_RETURNTOMENU = true;
std::string user_returntomenu;
// Check if the player wishes to make another conversion or exit the program
while (BOOL_RETURNTOMENU == true)
{
std::cout << "\nDo you wish to make another conversion? Y/N: ";
std::cin >> user_returntomenu;
std::cin.ignore();
if (user_returntomenu == "Y" || user_returntomenu == "y" || user_returntomenu == "N" || user_returntomenu == "n")
{
if (user_returntomenu == "Y" || user_returntomenu == "y")
{
std::cin.clear();
std::cin.ignore();
menu();
}
else
{
std::cout << "\nGoodbye";
BOOL_RETURNTOMENU = false;
}
}
else
{
std::cout << "\nBad Entry! Numbers not allowed! Please enter Y or N\n";
std::cin.clear();
std::cin.ignore();
}
}
CONVERTER_RUNNING = false;
return CONVERTER_RUNNING;
}
// Writing the menu() function to enable loopback from the restart function
void menu()
{
int user_selection = 0;
double celsius_amount = 0;
double fahrenheit_amount = 0;
std::cout << "Welcome to the Temperature Converter!\n\n";
std::cout << "1. Convert Celsius to Fahrenheit\n";
std::cout << "2. Convert Fahrenheit to Celsius\n";
std::cout << "3. Exit program\n";
UserSelectionValidate(user_selection);
if (user_selection == 1)
{
// Run Celsius to Fahrenheit function and retrieve the values to cout here
CelstoFahr(celsius_amount, fahrenheit_amount);
// cout the amounts received from the function
std::cout << "\n" << celsius_amount << " degrees Celsius is equal to " << fahrenheit_amount << " degrees Fahrenheit";
}
else if (user_selection == 2)
{
// Run Fahrenheit to Celsius function and retrieve the values to cout here
FahrtoCels(celsius_amount, fahrenheit_amount);
// cout the amounts received from the function
std::cout << "\n" << fahrenheit_amount << " degrees Fahrenheit is equal to " << celsius_amount << " degrees Celsius";
}
else if (user_selection == 3)
{
std::cout << "\nGoodbye";
}
else
{
std::cin.clear();
std::cin.ignore();
std::cout << "\nPlease enter a number between 1 and 3 for your selection!\n\n";
UserSelectionValidate(user_selection);
}
}
int main()
{
// Declare boolean variable to keep converter running
bool CONVERTER_RUNNING = true;
while (CONVERTER_RUNNING == true)
{
menu();
UserRestart();
}
pauseAtEnd();
return 0;
}
Here is one issue:
UserSelectionValidate(user_selection);
This can't have an effect on user_selection, since it is passed by value, and the return value isn't used. Perhaps you meant
user_selection = UserSelectionValidate();
And just have the user_selection declared locally in UserSelectionValidate:
int UserSelectionValidate()
{
// Declaring cin_fail_check to enable me to have the cin.fail() as a function
double cin_fail_check = 0;
// Perform cin.fail() on the users input then grab that input and clone it to user_selection
CinFailCheck(cin_fail_check);
int user_selection = cin_fail_check;
std::cin.clear();
std::cin.ignore();
return user_selection;
}
There is a similar issue with CinFailCheck().
You need to write correct code to store the input user_selection.
std::cout << "Welcome to the Temperature Converter!\n\n";
std::cout << "1. Convert Celsius to Fahrenheit\n";
std::cout << "2. Convert Fahrenheit to Celsius\n";
std::cout << "3. Exit program\n";
UserSelectionValidate(user_selection);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Replace above line with:
std::cin >> user_selection;
Then make sure that you ask for input values to be converted. You can do this.
You need to understand pass by value, and pass by reference. In almost all your functions you are passing by value and not using the return value. When you pass by value, a local variable is created (on the stack) by copying the one passed to it. When you modify it, you are not modifying the original variable passed.
For instance, in the code below, cin_fail_check never changes, it will always have the initialization value of 0, because CinFailCheck does not modify it; you can see how you would get endless loops from this.
// Declaring cin_fail_check to enable me to have the cin.fail() as a function
double cin_fail_check = 0;
// Perform cin.fail() on the users input then grab that input and clone it to user_selection
CinFailCheck(cin_fail_check);
int user_selection = cin_fail_check;
Change your function definitions to take references. For instance: double CinFailCheck(double& cin_fail_check) or use the return value.
"When to pass parameters by value, reference, and pointer"
http://www.cplusplus.com/articles/z6vU7k9E/

How to assign an enum value to a double variable defined by the user ?? C++

Hello i am a student so i wanted to say sorry in case my writing is tiring, feel free to correct me .
i am having the following problem i am trying to assign an enum int value to another double variable to make one multiplication.
so the variable costOfRoom should take the value D or T or S which belong to an enum. (D=200 ,T=150,S=110)
this must be done by the user .
But cant find any way , i tried to make the second variable a string type but its not working again. it will just take the chars normally as a string would do :(
Also tried cin >> type_Ofroom costofroom ;
but i think that this is used in Java??
Searched the forum also haven't any similar answer :(
The program runs fine it doesn't have any compiling errors :)
Thanks for your time
/* build a software system which will allow a hotel receptionist,
to enter in bookings for guests who come to the desk.
The system should display the room options as:
Room Price Code
---------------------------------------------------------------
Deluxe Room £200 D
Twin Room £150 T
Single £110 S
The receptionist should be prompted to enter in the room type and the number of
nights a guest wishes to stay for and then calculate the amount
they need to pay.
*/
// solution
#include <iostream>
using namespace std;
int main() {
// decleration of variables
double number_OfDays = 0, Totalcost = 0, costofroom = 0;
enum type_Ofroom { D = 200, T = 150, S = 150 };
cout << "enter the type of the room " << endl << endl;
//input of room type
cin >> costofroom; // **here is the problem** i am trying to give the
// values of the enum varaiable
// it should have D or T or S but i cant make it
cout << "enter the number of the days " << endl << endl;
//input of days
cin >> number_OfDays;
// calculation
Totalcost = costofroom * number_OfDays;
// result
cout << "the costumer has to pay " << Totalcost << " pounds" << endl << endl;
return 0;
}
You can read into a double, and then check against your enum values:
//input of room type
while (1)
{
cin >> costofroom;
if (costofroom == 0.0)
costofroom = D;
else if (costofroom == 1.0)
costofroom = T;
else if (costofroom == 2.0)
costofroom = S;
else
{
cout << "You didn't enter a valid option" << endl;
continue;
}
break;
}
However, it would be better to read into an int, and then set your double afterward.
double costofroom;
int option;
...
//input of room type
while (1)
{
cin >> option;
if (option == 0)
costofroom = D;
else if (option == 1)
costofroom = T;
else if (option == 2)
costofroom = S;
else
{
cout << "You didn't enter a valid option" << endl;
continue;
}
break;
}
The user can only input characters. cin will convert groupings of numbers to an int (e.g. 123) or or double (e.g. 123.5). It will also handle non-numeric groupings to std::strings (e.g. hello) or individual characters (e.g. c).
Once you have the user's input, you can convert them to your enum. You can use if statements, case statements or some type of table look up to do this.

Variables seem to be changing value on their own

Ok so my project is a program that analyses a .txt file that has a bunch of DNA strands of varying lengths. I got it all to work in 3 functions but my teacher wants us to us oo programming. So i put my code in a class and broke it up into different functions. Now, however my variables seem to randomly change their value and I don't know why.
I ran a bunch of tests with my "sum" variable (but it is not the only one doing this) and it calculates the correct value in the function but if I cout the value of "sum" back in my main, the value is changed to a ridiculous number.
Here is the code: it is not my whole program just where the problem variable is and how it is used.
If this isnt enough code to show the problem i can add more i just didnt want to make it cluttered.
DNAProcessing.cpp
void DNAProcessing::CalcSumAndMean()
{
int lineLength = 0;
int lineCounter = 0;
int wholeFileStringLen = 0;
double sum = 0;
double mean = 0;
string wholeFileString = "";
string line;
bool filefail = false;
ifstream DNAFile;
DNAFile.open(nameoffile.c_str());
if(DNAFile.fail())
{
filefail = true;
return;
}
else
{
cout << "\nYour data was processed\n" << endl;
}
while(DNAFile >> line)
{
//cout << line << endl;
lineCounter += 1;
lineLength = line.length();
sum += lineLength;
wholeFileString += line;
}
cout << "sum: " << sum << endl; // with my test .txt file this outputs 736
mean = (sum / lineCounter);
wholeFileStringLen = wholeFileString.length();
cout << "sum: " << sum << endl; // with my test .txt file this outputs 736
}
main.cpp
int main()
{
srand(time(0));
bool noexit = true;
string yesorno;
string filename;
while(noexit == true)
{
cout << "Would you like to process a list of DNA strings? (y/n)" << endl;
cin >> yesorno;
if((yesorno == "y") || (yesorno == "Y" ))
{
cout << "please input the name of the file you wish to process." << endl;
cin >> filename;
DNAProcessing DNAStrandFile(filename);
DNAStrandFile.CalcSumAndMean();
cout << "sum: " << DNAStrandFile.sum << endl; //for some reason sum turns into 3.18337e-314 and i have no clue why
if (DNAStrandFile.filefail == false)
{
cout << "sum: " << DNAStrandFile.sum << endl; // same here
DNAStrandFile.CalcNucleobaseRelProb();
DNAStrandFile.CalcBigramRelProb();
DNAStrandFile.CalcVarianceAndStndDev();
DNAStrandFile.CalcNormRand();
DNAStrandFile.PrintData();
DNAStrandFile.PrintNewList();
}
else
{
cerr << "No file found" << endl;
}
}
else if((yesorno == "n") || (yesorno == "N"))
{
noexit = false;
}
else{}
}
}
output while passing my test .txt file into this program.
sum: 736
sum: 736
sum: 3.18337e-314
sum: 3.18337e-314
Since sum is declared as double, it's value of 0 may not be stored exactly as zero, for all practical purposes, value of 3.18337e-314 can be considered as zero. You may define a threshold value
double epsilon = 0.00001 ; // depending on precision
and if sum < epsilon, sum = 0.0 (not needed though)
In your example, you have used sum as a local variable as well, either don't declare local variable, just use the member variable or declare the local variable as different name to avoid confusions
The value of a local variable is valid within the scope of the function,thats why you are getting correct answer inside method.
But no value is returned back,therefore garbage value is printed in the main.
Try sending the variable in the method by reference, then their exact value will be available in main also. Try it.

C++ string variables with if statements

I've tried re-defining these variables in every imaginable way possible
to try and get this line to work. I'm just going to give one example
here to represent what's troubling me.
double const FRAME_COST = 45.00;
string input;
char yes,
no;
int frames;
cout << "Do you want additional frames? Type yes/no: ";
cin >> input;
if (input == yes){
cout << "How many?"
cin >> frames;
frames = frames * FRAME_COST;
}
// The problem is in **the if statement**
// I need to use a string not a bool (according to my professor)
// I can't get the compiler to recognize the **if statement**
// I realize this isn't practical, but he always throws curve balls.
Your current program has undefined behavior, because yes and no are character variables that have not been initialized, and you are using one of them in a comparison.
To fix, remove the declarations of yes and no (you do not need them), and use a string literal instead:
if (input == "yes") {
...
}
Note: your comparison may be too strict, because it is case-sensitive. It will take a yes, but it would not take a Yes or a YES as an answer. To address this you may want to convert the input string to lower case before the comparison.
const string YES = "yes";
const string NO = "no";
const double FRAME_COST = 45.0;
int main()
{
string input;
double frames;
cout << "Hello World" << endl;
cin >> input;
if(input == YES)
{
cout << "How many?" << endl;
cin >> frames;
frames = frames * FRAME_COST;
cout << frames << endl;
}
return 0;
}
Just having a char named "yes" and another char name "no" is not sufficient, especially as you never actually gave them any values. I think you meant to write:
if (input == "yes") {
input == yes needs to be input == "yes" the quotes let the compiler know it's a string and not an identifier. I also think this might be helpful.
You need to do the comparison with a string or character array.
if (input == yes)
This line does nothing as yes is a character pointer that is never initialized. It should be
if (input == "yes")
And you do not need the yes variable (alternatively, you can declare a constant string with the values to check: e.g. const std::string YES("yes");)
Note, you should probably also account for case-sensitivity.
Additionally, you are multiplying an integer frames by a double FRAME_COST (presumably to get the total cost?). This will result in a truncated integer value since you are storing it in an int. If you want the cost to be in dollars and cents, you should store it in a double or float:
double cost = frames * FRAME_COST;
yes and no should be string constants (if you want to make them perfectly match with the input), either const std::string or const char* (or auto) but you have to assigh a value.
double const** FRAME_COST = 45.00;
string input;
const char* yes = "yes"
const char* no = "no";
int frames;
cout << "Do you want additional frames? Type yes/no: ";
cin >> input;
if (input == yes){ // exact comparison (maybe add a space trim of input?)
cout << "How many?"
cin >> frames;
frames = frames * FRAME_COST;
}
Instead of creating an if statement for only one input, is there a way of doing it with multiple inputs for one if statement without having to create several if statements?
for example...
string input;
cout << "Are you Bob?";
if (input == "yes", "no", "maybe"){
cout << "Sure...";
}else {
cout << "CANNOT COMPUTE";
}
Every time I try this, the input can be anything, and it will act as if I said "yes", "no", or "maybe".
#include <iostream>
#include<cmath>;
using namespace std;
int main()
{
double const FRAME_COST = 45.00;
string input;
int frames;
cout << "Do you want additional frames? Type yes/no: ";
cin >> input;
if (input == "yes"){
cout << "How many?";
cin >> frames;
frames = frames * FRAME_COST;
cout<<frames<<endl;}
else
{cout<<"please enter yes for additional frames";
}
//ALL ERRORS ARE SOLVED;
//ENJOY
//FOR MORE HELP YOU CAN CONTACT ME WHATSAPP +923034073767.
// The problem is in **the if statement**
// I need to use a string not a bool (according to my professor)
// I can't get the compiler to recognize the **if statement**
// I realize this isn't practical, but he always throws curve balls.
return 0;
}