C++ string array & for loop doesnt work as i expected - c++

#include <iostream>
using namespace std;
int main()
{
char num[10];
int a;
cout << "Odd or Even"<< endl;
for(;;)
{
cout << "Enter Number:" ;
cin >> num;
cout << endl;
for(a=9;a>=0;a--)
{
if(num[a]!='\0 && num[a]!=' ')
break;
}
if(num[a]==1 || num[a]==3 || num[a]==5 || num[a]==7 || num[a]==9)
cout << "Odd" << endl;
else
cout << "Even" << endl;
}
}
I am a rookie of C++,and I wrote a program to discriminate if a number is even or odd,
but no matter what number I enter, it only outputs "Even".
So I added these to find out when did the loop breaks:
cout << a << endl;
cout << "\"" << num[a] << "\"" << endl;
Result:
Enter Number:11
9
" "
Even
the for loop beraks when num[9]=' '? Which will lead to else and always output "Even".

You are confused about the character '1' and the number 1. They are different.
Instead of
if(num[a]==1 || num[a]==3 || num[a]==5 || num[a]==7 || num[a]==9)
you need
if(num[a]=='1' || num[a]=='3' || num[a]=='5' || num[a]=='7' || num[a]=='9')
Update
There is one more problems that is probably tripping you up.
num is not initialized. Zero-initialize it. Remember 0 is not the same as the character '0'.
char num[10] = {0};
Move the initialization of num inside the for loop. That will eliminate the problem of data from a previous execution of the loop from affecting the current execution of the loop.
Here's a version that works for me.
#include <iostream>
using namespace std;
int main()
{
cout << "Odd or Even"<< endl;
for(;;)
{
char num[10] = {0};
int a;
cout << "Enter Number:" ;
cin >> num;
cout << endl;
for(a=9;a>=0;a--)
{
if(num[a]!='\0' && num[a]!=' ')
break;
}
cout << num[a] << endl;
if(num[a]=='1' || num[a]=='3' || num[a]=='5' || num[a]=='7' || num[a]=='9')
cout << "Odd" << endl;
else
cout << "Even" << endl;
}
}
PS
You can replace the line
if(num[a]!='\0' && num[a]!=' ')
by
if(isdigit(num[a]))
That makes more sense to me.

If you are doing this with c++ there are much easier ways! Consider the following:
while (!done) {
string inputline;
getline(cin, inputline); //Now we have a string with the users input!
stringstream ss; // stringstreams help us parse data in strings!
int num; // We have a number we want to put it into.
ss >> num; // We can use the string stream to parse this number.
// You can even add error checking!
// Now to check for odd even, what do we know about even numbers? divisable by 2!
if (num % 2 == 0) // No remainder from /2
cout << Even << '\n'
else
cout << Odd << '\n'
}
see how you go with that!
Warning Untested code

You did a mistake (typo) here in this line..
if(num[a]!='\0 && num[a]!=' ')
it should be
if(num[a]!='\0' && num[a]!=' ')

Related

calling function on while loop

I'm making a calculator program but I already encounter a problem. Well, my code is in a loop that will call a function to display the choices and then ask the user to pick, a/s/m/d are the choices. If the input is on the choices, it will proceed to the next step. Otherwise, it will loop and then call the function again.
#include <iostream>
using namespace std;
void home()
{
cout << "\nChoose your operation:" << endl;
cout << "\tType [A] for Addition" << endl;
cout << "\tType [S] for Subtraction"<< endl;
cout << "\tType [M] for Multiplication" << endl;
cout << "\tType [D] for Division" << endl;
}
int main()
{
char operation;
bool no_operator = true;
int design = 73;
for (int i = 0; i < design; i++){
if (i == 25){
cout << " WELCOME TO CALCULATOR ";
i += 22;
}
else i == 72 ? cout << "*\n" : cout << "*";
}
while (no_operator){
home();
cout << "\nOperation: ";
cin >> operation;
if (operation == 'A' || operation == 'a')
{
cout << "\nIt will going to add numbers";
no_operator = false;
}
else if (operation == 'S' || operation == 's')
{
no_operator = false;
cout << "\nIt will going to subtract numbers";
}
else if (operation == 'M' || operation == 'm')
{
no_operator = false;
cout << "\nIt will going to multiply numbers";
}
else if (operation == 'D' || operation == 'd')
{
no_operator = false;
cout << "\nIt will going to divide numbers";
}
else
{
cout << "\tInvalid Input: You must enter A/S/M/D only\n";
//home();
}
}
return 0;
}
My problem is it will run the '''home()''' in else statement even if the input is correct on the second loop.
I want to stop the '''home()''' to be called when the input is correct
Your code works perfectly fine. Make sure you're inputting the correct letters.
Also for this code, a "do while()" loop would be better.
You program is working perfectly fine as the input is correct it does not show the home rather print the message it will going to divide etc.

To confirm only 1 and 0 exist in the Binary

I wanted to use only 1 and 0 for the binary. But instead the answer keep giving me the 2nd option with whatever number I typed. I had tried where did I programmed wrongly but unfortunately I still can't find it. So I hoped that I could get some help here.
#include<iostream>
#include<cmath>
using namespace std;
int DualzahlZuDezimal(long long n)
{
int dez = 0;
int i = 0, rem;
while (n != 0)
{
rem = n % 10;
n /= 10;
dez += rem * pow(2, i);
++i;
}
return dez;
}
string a;
int main()
{
long long n;
int dez;
cout << "Test Ein- und Ausgabe : \n";
cout << "----------------------- \n";
cout << "Eingabe einer Dualzahl : ";
cin >> n;
if ((n == '1') && (n == '0'))
{
cout << "Dual : " << n << endl;
cout << "Dezimal : " << DualzahlZuDezimal(n) << endl;
cout << "cin ok ? : ja-ok" << endl;
return 0;
}
else
{
cout << "Dual : 0" << endl;
cout << "Dezimal : 0" << endl;
cout << "cin ok ? : nein-nicht ok" << endl;
return 0;
}
}
If I understand this right, you want the user to enter a binary number, like 10001101001, and you will show the decimal equivalent (1129 in this case).
There are 2 general ways to do that yourself:
You can read the value as a number, as you do, and then apply your conversion
process, except that you check that rem is either 0 (in which case you do
nothing), or 1 (in which case you add the power of 2). If it's another value,
you report the error, and return 0.
You can read the value as a std::string instead. Then you can use
std::find_first_not_of()
to check for contents other than 0 or 1:
if (n.find_first_not_of("01") != string::npos) { /* complain */ }
but then you need to do the conversion based on characters.
But the best approach is not to reinvent the wheel and instead let the standard library handle it for you via stol():
#include <cstddef>
#include <iostream>
#include <string>
using namespace std;
int
main()
{
string text;
cout << "Enter a binary number: " << flush;
cin >> text;
size_t endpos = 0;
long decimal_number = stol(text, &endpos, 2); // base 2 == binary
if (endpos != text.size()) {
cerr << "'" << text << "' is not a valid binary number!" << endl;
return 1;
}
else {
cerr << "binary number: " << text << endl;
cerr << "decimal number: " << decimal_number << endl;
return 0;
}
}
Keep in mind that input from the console is text. If you need to check that the text matches a particular format (in this case, consists entirely of 1's and 0's), the simplest approach is to look at that text:
std::string input;
std::cin >> input;
bool input_is_valid = true;
for (int i = 0; input_is_valid && i < input.length(); ++i) {
if (input[i] != '0' && input[i] != '1')
input_is_valid = false;
}
then, if the input is valid, convert the text to a numeric value:
long long n = std::stoll(input);

How to Accept [ENTER] key as an invalid input and send out error message

This is a program that grade user inputs for the questions of Driver's License Exam.
I'm having trouble of validating the user input.
I'd like to accept the [ENTER] key as an invalid input and proceed to my validation rather than just go to an empty line and cannot process to the next question. Purpose is to send out error message and that no input is given and [ENTER] key is not valid input and only accept one more chance to enter valid input which are a/A, b/B, c/C, or d/D. So that is why I'm using if statement here instead of loop.
I tried if (testTakerAnswers[ans] == (or =) '\n') {} but still doesn't solve the problem of newline.
I include curses.h in here hope to use getch() statement from the other post but somehow I can't manage to work in my code with an array instead of regular input.
I'm looking for other methods as well rather than getch()
So should I adjust my bool function, or directly validate input in main() function.
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <curses.h>
using namespace std;
const unsigned SIZE = 20; // Number of qns in the test
char testTakerAnswers[SIZE]; //Array to hold test taker's answers
bool validateInput(char);
class TestGrader
{
private:
char answers[SIZE]; // Holds the correct answers // Answer is array
int getNumWrong (char[]);
void missedQuestions (char[]);
public:
void setKey(string); // Initialize object with standard keys
void grade(char[]); // Grades the answers from tester
};
void TestGrader::setKey(string key){
if (key.length()!=SIZE){
cout << "Error in key data.\n";
return;
}
for (unsigned pos = 0; pos < SIZE ; pos ++)
answers [pos] = key [pos];
}
void TestGrader::grade(char test[])
{
int numWrong = getNumWrong(test);
if (numWrong <= 5)
cout << "Congratulations. You passed the exam.\n";
else
cout << "You did not pass the exam. \n";
cout << "You got " << (SIZE-numWrong) << " questions correct. \n";
if (numWrong > 0){
cout << "You missed the following " << numWrong << " questions: \n";
missedQuestions(test);
}
}
int TestGrader::getNumWrong(char test[])
{
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
counter++;
}
}
return counter;
}
void TestGrader::missedQuestions(char test[])
{
// cout << testTakerAnswers[i]; This is to print taker's answers
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
cout << "\n" << i + 1 << ". Correct answers: " << answers[i];
counter++;
}
}
}
bool validateInput(char ans){ // Only A, B, C, D valid input
if (toupper(ans)!='A' && toupper(ans)!= 'B' && toupper(ans)!='C' && toupper(ans)!= 'D'){
cout << "\n********************WARNING*******************\n";
cout << "Invalid input! Enter only a/A, b/B, c/C, or d/D\n";
return false;
}
if (testTakerAnswers[ans] == '\n'){
return false;
}
return true;
}
int main()
{
const int NUM_QUESTIONS = 20;
string name; //Test taker's name
char doAnother; //Control variable for main processing loop
TestGrader DMVexam; //Create a TestGrader object
DMVexam.setKey("BDAACABACDBCDADCCBDA");
do {
cout << "Applicant Name: ";
getline(cin,name);
cout << "Enter answer for " << name << ".\n";
cout << "Use only letters a/A, b/B, c/C, and d/D. \n\n";
for (int i = 0; i < NUM_QUESTIONS; i++){
// Input and validate it
do{
cout << "Q" << i+1 << ": ";
cin >> testTakerAnswers[i];
if (!validateInput(testTakerAnswers[i])){
cout << "You get one more chance to correct.\nOtherwise, it count as wrong answer.";
cout << "\n*********************************************";
cout << "\nRe-enter: ";
cin >> testTakerAnswers[i];
cout << '\n';
break;
}
}while(!validateInput(testTakerAnswers[i]));
}
//Call class function to grade the exam
cout << "Results for " << name << '\n';
DMVexam.grade(testTakerAnswers);
cout << "\nGrade another exam (Y/N)? ";
cin >> doAnother;
while (doAnother != 'Y' && doAnother != 'N' && doAnother != 'y' && doAnother != 'n'){
cout << doAnother << " is not a valid option. Try Again y/Y or n/N" << endl;
cin >> doAnother;}
cout << endl;
cin.ignore();
}while(doAnother != 'N' && doAnother != 'n');
return 0;
}
Your issue is cin >> testTakerAnswers[i]; cin is whitespace delimited, that means that any whitespace (including '\n') will be discarded. So testTakerAnswers[i] can never be '\n'.
I'm not sure exactly what you want to do, but possibly try
getline(cin,input_string);
then
input_string == "A" | input_string == "B" | ...
So if only the enter key is pressed, input_string will become "".

Algorithm that counts character's doesn't count apostrophes

This is the function of a larger program. This function just figures out how many characters are in an alphanumeric word. Weird thing is, it counts apostrophes when running it in Xcode, but not after compiling and running it in Terminal. Any suggestions?
#include <iostream>
#include <iomanip>
#include <ctype.h>
using namespace std;
int WordLength();
void DisplayTable(int WF[]);
int main()
{
int WordFrequency[16]={0};
int TempLengthStorage=0;
TempLengthStorage=WordLength();
while (TempLengthStorage!=0)
{
if (TempLengthStorage==1)//skipping subscript 0 - not using it
++WordFrequency[1];
else if (TempLengthStorage==2)
++WordFrequency[2];
else if (TempLengthStorage==3)
++WordFrequency[3];
else if (TempLengthStorage==4)
++WordFrequency[4];
else if (TempLengthStorage==5)
++WordFrequency[5];
else if (TempLengthStorage==6)
++WordFrequency[6];
else if (TempLengthStorage==7)
++WordFrequency[7];
else if (TempLengthStorage==8)
++WordFrequency[8];
else if (TempLengthStorage==9)
++WordFrequency[9];
else if (TempLengthStorage==10)
++WordFrequency[10];
else if (TempLengthStorage==11)
++WordFrequency[11];
else if (TempLengthStorage==12)
++WordFrequency[12];
else if (TempLengthStorage==13)
++WordFrequency[13];
else if (TempLengthStorage==14)
++WordFrequency[14];
else if (TempLengthStorage>=15)
++WordFrequency[15];
TempLengthStorage=WordLength();
}
DisplayTable(WordFrequency);
}
int WordLength()
{
int LetterCount=0;
int EndOfWord=0;
char Input;
char NextChar;
cin.get(Input);
while (EndOfWord!=1 && !cin.eof())
{
if (Input==' ' || Input=='\n' || Input=='.' || Input=='!' || Input=='?' || Input==',')
{//do nothing if whitespace or punctuation, essentially skips over them
}
else if (Input=='-')
{
NextChar=cin.peek();
if ((isalpha(NextChar)) || (isnumber(NextChar)))//this includes the hyphen in words that have hyphens (refer to funtion notes)
++LetterCount;
if (NextChar=='\n')//for cases where the hyphen doesn't add to word length (refer to function notes)
{
cin.get(Input);//dont count it and get next character
}
}
else if (Input=='\'')
++LetterCount;
else if ((isalpha(Input)) || (isnumber(Input)))
{
++LetterCount;
NextChar=cin.peek();
if (NextChar==' ' || NextChar=='\n' || NextChar=='.' || NextChar=='!' || NextChar=='?' || NextChar==',' || NextChar==')')//included ) as a condition to end words for cases such as (219)
{
EndOfWord=1;
}
}
cin.get(Input);
}
return LetterCount;
}
void DisplayTable(int WF[])
{
int TotalWords=0;
float TotalLetters=0;//made a float for float based masth later on when finding average
float Average=0;
cout << endl;
cout << "Word Length Frequency" << endl;
cout << "----------- ---------" << endl;
for (int i=1; i<=15; ++i)
{
/*This portion of the loop displays the table*/
cout << " ";
cout << setw(2) << i;
cout << " ";
cout << WF[i] << endl;
/*this portion of the loop does the calculations needed to find the average word length*/
TotalWords += WF[i];
TotalLetters += (i * WF[i]);
}
cout << "\nTotal Words = " << TotalWords << endl << endl;
cout << "Total Letters = " << TotalLetters << endl << endl;
Average = TotalLetters/TotalWords;
cout << "Average Word Length: " << Average << endl;
}
I used "Ain't" in both situations, just for testing purposes.

Conditional cin giving stacked cout messages

Using C++ (g++-4.7 on Mint 16).
Code is a unrefined (and unfinished) Tic-Tac-Toe game.
#include <iostream>
using namespace std;
int main()
{
//initial data
char turn='A';
char ttt[] = {'1','2','3','4','5','6','7','8','9'};
int move;
int over=0; //0 is no, 1 is yes
int valid=0;
while ( over == 0)
{
//display
cout << "\n" << ttt[0] << "|" << ttt[1] << "|" << ttt[2] <<"\n-----\n";
cout << ttt[3] << "|" << ttt[4] << "|" << ttt[5] <<"\n-----\n";
cout << ttt[6] << "|" << ttt[7] << "|" << ttt[8] <<"\n\n Choose a number (Player " << turn << "):";
//ask enter for play with turn
cin >> move;
cout << "\n";
valid = 0;
while (valid == 0)
{
//check if input is valid
if (((move > 0) and (move < 10)) and
((ttt[move-1] != 'A') and (ttt[move-1] != 'B')) and
(cin))
{
ttt[move-1] = turn;
valid=1;
}
else
{
cout << "Invalid slot. Choose a number (Player " << turn << "):";
cin >> move;
cout << "\n";
}
}
//check if done if no //change turn then goto //display
if (((ttt[0]==ttt[1]) and (ttt[1]==ttt[2])) or
((ttt[3]==ttt[4]) and (ttt[4]==ttt[5])) or
((ttt[6]==ttt[7]) and (ttt[7]==ttt[8])) or
((ttt[0]==ttt[3]) and (ttt[3]==ttt[6])) or
((ttt[1]==ttt[4]) and (ttt[4]==ttt[7])) or
((ttt[2]==ttt[5]) and (ttt[5]==ttt[8])) or
((ttt[0]==ttt[4]) and (ttt[4]==ttt[8]))or
((ttt[2]==ttt[4]) and (ttt[4]==ttt[6])))
{
//display winner or say draw
cout << "Player " << turn << " wins!\n";
over=1;
}
else
{
//change turn
if (turn=='A')
{ turn='B';
}
else
{ turn='A';
}
}
}
return 0;
}
There seem to be a bug on the code. On the part where check if input is valid the and (cin) seem to be failing.
When entering a character, (Instead of a number) it output continuously stacks of:
Invalid slot. Choose a number (Player A or B):
I tested the rest of condition without it, it was all working well. Is there a problem on the code or is this really "cin" problem? I've also tried out !(!cin) but it's the same scenario.
You must clear the fail bit from the cin stream in your else block.
When you enter a character that isn't an integer, the cin stream sets the fail bit, which you correctly check for in your if statement, but you never clear it afterward. This causes your input validity check to be false forever.
#include <limits>
...
else
{
cin.clear(); // Add this line
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // And this one
cout << "Invalid slot. Choose a number (Player " << turn << "):";
cin >> move;
cout << "\n";
}
For additional information, see the documentation for std::basic_ios::clear
Update: see this question and this question for similar problems.
Essentially, you also need to tell cin to ignore whatever is in the stream or it will continually set the fail bit with its bad contents you haven't cleared yet. I modified the above snippet to work.