Sorry if it's something simple, but I'm new to C++ and haven't really gotten a good hold on it, yet. I need to build a calculator whose only named variables are pointers, and this is what I have so far, but I keep getting errors and I can't figure out why. Every error that always related to my if construct, though.
int main()
{
//Creating variables
//Values to perform operations on
float *aptr = new(nothrow)float;
float *bptr = new(nothrow)float;
float *ansptr = new(nothrow)float;
int *endptr = new(nothrow)int;
char *operationptr = new(nothrow)char;
cout << "Simple Operation Calculator" << endl; //Displays program name
cout << "Performs +, -, *, or / on any two real operands." << endl; //Describes nature of program to user
*endptr = 1;
while(*endptr = 1) //Creates a loop so that the user may perform as many operations as desired
{
//Prompts the user for the first operand
cout << "First operand: " << endl;
cin >> *aptr;
//Prompts user for operator
cout << "Operator(+,-,*,/): " << endl;
cin >> *operationptr;
//Prompts user for second operand
cout << "Second operand: " << endl;
cin >> *bptr;
//Performs requested operation
if(*operationptr == '+' || *operationptr == 'plus')
{
*ansptr = *aptr + *bptr;
}
else if(*operationptr == '-' || *operationptr == 'minus')
{
*ansptr = *aptr - *bptr;
}
else if(*operationptr == '*' || *operationptr == 'times')
{
*ansptr = *aptr * *bptr;
}
else if(*operationptr == '/' || *operationptr == 'divided by')
{
if(*bptr = 0)
{
cout << "Cannot divide by zero. Terminating program." << endl;
*endptr = 2;
break;
}
*ansptr = *aptr / *bptr;
}
else
{
cout << "Invalid operand input. Terminating program." << endl;
*endptr = 2;
break;
}
//Displays results
cout << *aptr << *operationptr << *bptr << " = " << *ansptr << endl;
//Asks user if they wish to perform another operation. If so, they stay in loop. If not, then break from loop.
cout << "Do you wish to perform another operation? (1 = yes, 2 = no)" << endl;
cin >> *endptr;
//If 1, loop repeats. If 2, program ends.
if (*endptr == 2)
{
cout << "Thank you for using my program. Goodbye!" << endl;
}
} //end while loop
return 0;
}//end main function
There are character literals (with ') and string literals (with "). Character literals have one character. String literals are arrays of characters. You can't write something like 'plus' because it has more than one character (well technically you can, but it's a multi-character literal, but lets not go there).
Nonetheless, this wouldn't make any sense because operationptr points at a single char object. A single char can't contain the entire word plus.
If you want to be able to accept plus as input, then I suggest you start using strings. In fact, use std::string.
As a side note, you are using pointers and dynamic allocation far too often. You are also forgetting to delete the objects that you create with new - this is a memory leak. I imagine you have come from a language that uses new for all object creation. In C++, this is not necessary (and is not a good practice). Instead, you can declare objects like so:
float aptr;
There is no need to dereference this object. You can just use aptr directly as a float.
'plus'
is a character constant, and can't contain more than one character.
'+' is fine, since it's a single character in a constant.
As per the comment on this answer,
'plus' could be ok, if the compiler is not expecting a char.
Related
I am trying to get input from the user and need to know a way to have the program recognize that the input was or was not a double/char this is what i have right now... but when you type an incorrect type of input
1) the double test one just loops infinatly
2) the char one won't stop looping even with the correct imput
int main () {
double _double = 0;
bool done = true;
while ( done ) {
cout << "Please enter a DOUBLE:\n" << endl;
cin >> _double;
if ( _double > 0 ) { done = false; }
if ( _double < 0 ) { cout << "\nthe number you entered was less than zero\nplease enter a valad number..." << endl; }
if(cin.fail()) { cin.clear(); }
}
done = false;
char _char = ' ';
while ( !done ) {
cout << "Please enter a CHAR" << "\n";
cout << "\t'y' = yes\n\t'n' = no" << endl;
cin >> _char;
if ( _char == 'y' || _char == 'n' ) { done = true; }
if ( ! (_char == 'y' || _char == 'n') ) { cout << "\nyou have entered an invald symbol... \n" << endl; }
if(cin.fail()) { cin.clear(); }
}
The best bet is always to read your input as strings. You can then use functions like std::strtod() to test and convert to doubles. Checking if streams have failed and then resetting them is error prone at best, and doesn't give you the possibility of producing good error messages.
For example:
string s;
cin >> s;
char * p;
double d = strtod( s.c_str(), & p );
if ( * p == 0 ) {
cout << "Read double: " << d << endl;
}
else {
cout << "Read string: " << s << endl;
}
The pointer 'p' will point to the first character that cannot be converted to a double. How exactly you handle that really depends on your app's logic.
The problem is that when you read something and cin sees the input can never be a double, it stops reading, leaving the stuff in the buffer that it didn't consume. It will signal failure, which you clear but you won't eat the remaining input that cin didn't eat up. So, the next time the same wrong input is tried to read again, and again...
The problem with the char one is that you have to press the return key to make it process any characters on most terminals (this does not happen if you make your program read from a file, for instance). So if you press y then it won't go out of the read call, until you hit the return key. However, then it will normally proceed and exit the loop.
As others mentioned you are better off with reading a whole line, and then decide what to do. You can also check the number with C++ streams instead of C functions:
bool checkForDouble(std::string const& s) {
std::istringstream ss(s);
double d;
return (ss >> d) && (ss >> std::ws).eof();
}
This reads any initial double number and then any remaining whitespace. If it then hit eof (end of the file/stream), it means the string contained only a double.
std::string line;
while(!getline(std::cin, line) || !checkForDouble(line))
std::cout << "Please enter a double instead" << std::endl;
For the char, you can just test for length 1
std::string line;
while(!getline(std::cin, line) || line.size() != 1)
std::cout << "Please enter a double instead" << std::endl;
If you want to read only 1 char and continue as soon as that char was typed, then you will have to use platform dependent functions (C++ won't provide them as standard functions). Look out for the conio.h file for windows for instance, which has the _getch function for this. On unix systems, ncurses provides such functionality.
cin >> _double will always get you a double, whether they typed in "42", "0" or "mary had a little lamb". You need to read the user input as a string, then test that string to see if it is a double. sscanf will return 0 if it can't convert the input string to the desired type:
cout << "Please enter a DOUBLE:\n" << endl;
string s;
cin >> s;
if( !sscanf(s.c_str(), "%lf", &_double) )
{
done = false;
cout << "Not a number, sparky. Try again." << endl;
continue;
}
Also, identifiers with leading underscores like you have are reserved by the language. Don't get in the habit of naming things like _double -- someday, they may not work.
I've been struggling with a homework assignment that counts the amount of instances a uppercase letters, lowercase letters, and numbers in a string. appears in a string.
I'm using a one-dimensional array with a constant size of 132 to store the entered string, and I need to use two functions. One needs to count the amount of letter occurrences in the string and the other function will execute the output something similar to above. I'm struggling most with the letter counting aspect of the program itself.
Currently, this is what my current homework resembles for the most part. It's a work in progress (of course) so errors in the code are very likely.
void LetterCount(char c_input[], int l_count)
{
// code to count letters
}
void CountOut(//not sure what should go here yet until counting gets figured out)
{
// code that handles output
}
int main()
{
const int SIZE = 132;
char CharInput[SIZE];
int LetterCount = 0;
cout << "Enter a string of up to 132 characters in size: ";
cin.getline(CharInput, SIZE);
cout << "You entered: " << CharInput << endl;
Count(CharInput);
CountOut(//not sure what goes here yet);
return 0;
}
The output would look something like:
a - 2
b - 1
c - 1
d - 0
e - 1
etc...
I've tried some experimentation with for loops to count the letters and have seen some examples of the function gcount(), but I haven't gotten anything to work. Does anyone have a suggestion as to how I would count the letters in an inputted string?
map is a very efficient data structure here
#include <iostream>
#include <map>
using namespace std;
int main(){
string str = "a boy caught 2 fireflies";
map<char, int> str_map;
for(auto x : str) ++str_map[x];
for(auto x : str_map) cout << x.first << ' ' << x.second << '\n';
}
What you want is to build a simple histogram, and it's pretty easy to do. Since what you're looking at is chars, and there can be 256 possible values of an 8-bit char (in practice your input string probably uses less, but we'll be conservative here because memory is cheap), you'll want to start with an array of 256 ints, all of them initialized to zero. Then iterate over the chars your string, and for each char in your string, use that char-value as an offset into the array(*), and simply increment that item in the array.
When you're done, all that remains is to iterate over the ints in the array and print out the ones that are non-zero, and you're done.
(*) you may want to cast the char to unsigned char before using it as an offset into the array, just to avoid any chance of it being interpreted as a negative array-index, which would result in undefined behavior (this is only an issue if your input string contains ASCII characters 128 and higher, so it may not matter in your case, but it's always good form to make code that does the right thing in all cases if you can)
As Jeremy frisner said you're building a histogram, but I disagree with the types used.
You'll want to declare your histogram like so:
size_t histogram[sizeof(char)*CHAR_BIT] = {0};
The size_t because you might overflow without it, and you need enough space if it's a nonstandard byte size.
As for printing it out. You should take a look at an ASCII table and examine which values you need to print out.
You could do it by comparing c-strings with other c-strings. But with chars and strings you can get errors like: "const *char cant be compared with strings". So you'll have to compare each c string(array) index with other c string indexes. In this program I use if statements to look for certain vowels. The way it works is that each "string alphabet_letter" is equal to it's respective lowercase and capital letters (for comparison). this is a very redundant way to do it and, if you want to count all total letters, perhaps you should try a different way, but this method doesn't use very complicated methods that require deeper understanding.
using namespace std;
int main(){
int vowel;
string A = "aA";
string E = "eE";
string I = "iI";
string O = "oO";
string U = "uU";
string str;
string str1;
bool userLength = true;
int restart = 0;
do{
cout << "Enter a string." <<endl;
getline(cin, str);
int VowelA = 0;
int VowelE = 0;
int VowelI = 0;
int VowelO = 0;
int VowelU = 0;
for(int x = 0; x < 100; x++){
if(restart == 1){
restart = 0;
x = 0;
}
if(A[0] == str[x]){
VowelA = VowelA + 1;
}
if(E[0] == str[x]){
VowelE = VowelE + 1;
}
if(I[0] == str[x]){
VowelI = VowelI + 1;
}
if(O[0] == str[x]){
VowelO = VowelO + 1;
}
if(U[0] == str[x]){
VowelU = VowelU + 1;
}
if(A[1] == str[x]){
VowelA = VowelA + 1;
}
if(E[1] == str[x]){
VowelE = VowelE + 1;
}
if(I[1] == str[x]){
VowelI = VowelI + 1;
}
if(O[1] == str[x]){
VowelO = VowelO + 1;
}
if(U[1] == str[x]){
VowelU = VowelU + 1;
}
int strL = str.length();
if(x == strL){
cout << "The original string is: " << str << endl;
cout << "Vowel A: "<< VowelA << endl;
cout << "Vowel E: "<< VowelE << endl;
cout << "Vowel I: "<< VowelI << endl;
cout << "Vowel O: "<< VowelO << endl;
cout << "Vowel U: "<< VowelU << endl;
cout << " " << endl;
}
}
char choice;
cout << "Again? " << endl;
cin >> choice;
if(choice == 'n' || choice == 'N'){userLength = false;}
if(choice == 'y' || choice =='Y')
{
restart = 1; userLength = true;
cin.clear();
cin.ignore();
}
//cout << "What string?";
//cin.get(str, sizeof(str),'\n');
}while(userLength == true);
}
/*
Sources:
printf help
http://www.cplusplus.com/reference/cstdio/printf/
This helped me with the idea of what's a vowel and whats not.
http://www.cplusplus.com/forum/general/71805/
understanding gets()
https://www.programiz.com/cpp-programming/library-function/cstdio/gets
Very important functional part of my program...Logic behind my if statements, fixed my issues with string comparison
What i needed to do was compare each part of one cstring with another c string
strstr compares two strings to see if they are alike to one another this source includes that idea-> https://www.youtube.com/watch?v=hGrKX0edRFg
so I got the idea: What is one c string was all e's, I could then compare each index for similarities with a c string whos definition was all e's.
At this point, why not just go back to standard comparison with strings? But you cant compare const chars to regular chars, so I needed to compare const chars to const chars
hence the idea sparked about the c strings that contained both e and E.
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string
https://stackoverflow.com/questions/18794793/c-comparing-the-index-of-a-string-to-another-string
Fixed Error with using incremented numbers outside of involved forloop.
https://stackoverflow.com/questions/24117264/error-name-lookup-of-i-changed-for-iso-for-scoping-fpermissive
understanding the use of getline(cin, str_name)
https://stackoverflow.com/questions/5882872/reading-a-full-line-of-input
http://www.cplusplus.com/reference/istream/istream/getline/
http://www.cplusplus.com/forum/beginner/45169/
cin.clear - cin.ignore --fixing issue with cin buffer not accepting new input.
https://stackoverflow.com/questions/46204672/getlinecin-string-not-giving-expected-output
*/
I'm very new to C++, just started learning using an online course about 30 minutes ago. I'm a little confused as to why this string comparison isn't working in a basic math script:
#include <iostream>
#include <string>
using namespace std;
int main() {
int one, two, answer;
char *oper;
cout << "Add two numbers\n\nEnter your first number" << endl;
cin >> one;
cout << "Choose an operator: + - * / %%" << endl;
cin >> oper;
cout << "Enter your second number" << endl;
cin >> two;
if (oper == "+") {
answer = one + two;
}
else if (oper == "-") {
answer = one - two;
}
else if (oper == "*") {
answer = one * two;
}
else if (oper == "/") {
answer = one / two;
}
else if (oper == "%%") {
answer = one % two;
}
cout << one << " " << oper << " " << two << " = " << answer << endl;
return 0;
}
The values for one, oper, and two are 1, "+", and 1 respectively, but in the end, 1 + 1 = 4201435 is printed out. None of the if/else if statements are being executed. What's causing this?
You're comparing char * using operator==. Either let oper be a std::string instead
std::string oper
To use the string comparison listed here: http://en.cppreference.com/w/cpp/string/basic_string/operator_cmp
or if you need to use a char * for some restriction, use strcmp:
if (!strcmp(oper, "+")) {
// ...
You also need to have your operand variable point at some buffer too, for the stream to read into. This is a little bit more complicated and I just recommend changing the type of oper to std::string.
The problem with the code you have is that it's comparing pointers to char arrays. What you get from your input methods is going to be a new string from the input stream and will never have the same address as the readonly strings in your program.
So since none of the condition is true, ans hasn't been assigned. So output it accounts for an undefined behavior.
The value starts from 0 and can then be calculated using any operand of Mathematics. The code compiles successfully but doesn't work. The terminal windows shows 'Abort', 'Retry' and 'Cancel'. The rule is that you cannot use 2 operands but just keep adding the previous number to present operand.
#include <iostream>
#include <cmath>
using namespace std;
void Input(double input);
int main()
{
double sign, input;
cout << "This program calculates any given number upto 1 decimal place using the following operators:" << endl;
cout << " '+' - Addition." << endl;
cout << " '-' - Subtraction" << endl;
cout << " '*' - Multiplication." << endl;
cout << " '^' - Root." << endl;
cout << " '/' - Division." << endl;
Input(input);
return 0;
}
void Input(double IN)
{
char q;
char sign;
int Val = 0.0;
cin >> sign >> IN;
while (IN != q)
{
if (sign = '-')
Val -= IN;
if (sign = '+')
Val += IN;
if (sign = '*')
Val *= IN;
if (sign = '/')
Val /= IN;
cout << endl << "Result so far is " << IN;
IN++;
}
}
Your main problem is
q is undefined so the while(IN != q) will become undefined behavior
in C++, for any primitive datatype = means assignment operator, and not a comparator operator. To compare something use == instead.
Val is a variable with int datatype but assigned with value 0.0 which is a float or double.
What your program do in the if statement is : (for example this if statement)
if (sign = '-')
The program assign the value of - which is 45 to the sign variable
The if statement check the variable sign for value 0
if the value is 0 then the statement considered false and the block is skipped
if the value is other than 0 then the statement considered true and enter the block
The program run the code inside the if block
The program do all of those 3 thing for every if statement in your code, and I rarely run my own code in Windows so I can't very sure why the program giving the Run-Time Check Failure #3-T error
A little advice, use switch whenever you need to use multiple if statement, since it is easier to read.
char iCharSelect()
{
//CHARACTER CHOICE
cout
<< "\n\n\n Choose Your Stoner:\n\n"
<< "\n 1 = Chris\n"
<< "\n 2 = James\n"
<< "\n 3 = Hunter\n"
<< "\n 4 = Antonio (Alt. Route)\n"
<< "\n\n Enter Character Number: ";
int iChar = INITIALIZED;
cin >> iChar;
//CHARACTER NAME STRING
string sCharName;
//CHARACTER CHECK
if (iChar == 1){sCharName = "Chris";}
else if (iChar == 2){sCharName = "James";}
else if (iChar == 3){sCharName = "Hunter";}
else if (iChar == 4){sCharName = "Antonio";}
else {
cout << "\n\n\n\tYOU GET NOTHING!!";
system("PAUSE>NUL");
//PROGRAM CLOSES HERE-------------------------------------
cout << iChar;
system("PAUSE>NUL");
}
char *chCharName = &sCharName[0];
return *chCharName; }
What am I doing wrong? The program closes at the marked point in the code and trying to print iChar yields nothing..?
I think you should do:
if (ichar == '1')
same for 2,3..
The way you do it, is ask if the char inserted hascii is equal to 1/2.. It does not equal, so you get to the last "if" statement.
You are returning a pointer return *chCharName; but you've labeled the function as char. One of your problems is that you need to label the function to return char*
char* iCharSelect()
The main issue with your code is that you do not set chCharName if none of those conditions in the if() statement are true. If this is the case, you will attempt to return the first character of an empty string, which leads to undefined behavior.
In addition, the end of the function uses pointers when there is no need to use pointers.
A reasonable implementation would look like this:
if ( sCharName.empty())
return '\0';
return sCharName[0];