My assignments requires me to keep accepting input from the user and output whether or not it is a palindrome until the word DONE is inputed.
Also, words like Bob must have an output of true because we must disregard case (upper/lower.)
This is my first time using C++.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string wordInput;
while (wordInput != "DONE")
{
cout << "Please enter a word: ";
cin >> wordInput;
int wordLength = wordInput.length();
int wordHalf = (wordLength / 2);
bool flag = false;
for (int i = 0; i <wordHalf; i++)
{
if (tolower((wordInput[i]) == tolower(wordInput[wordLength-1-i])))
{
flag = true;
}
else
{
flag = false;
break;
}
}
if (flag == true)
{
cout << "true"<<endl;
}
else
{
cout << "false"<<endl;
}
}
return 0;
}
It might have something to do with 'wordInput' being declared twice, once right before the while loop and once within it. It is mixing up what the while loops condition is looking at.
Your issue with words not being correctly identified comes from this line:
if(tolower((wordInput[i]) == tolower(wordInput[wordLength-1-i])))
If you look carefully, you set the parentheses incorrectly. Try this instead:
if(tolower(wordInput[i]) == tolower(wordInput[wordLength-1-i]))
Related
I have the following code and it somehow verify if the input is number, but the error occurs while looping back to ask the user for the second time to enter the number.
I can't figure it out.
#include <iostream>
#include <limits>
using namespace std;
void botVarification();
void userDecision();
bool isHuman(string humanInput);
int main()
{
botVarification();
return 0;
}
void botVarification()
{
string humanInput;
cout << "Enter the number to verify that you are not a bot: ";
cin >> humanInput;
bool isHuman = true;
do {
for (int humanInputvalidator; humanInputvalidator < humanInput.length() && isHuman; humanInputvalidator++) {
if (!(humanInput[humanInputvalidator] >= 48 && humanInput[humanInputvalidator] <= 57)) {
isHuman = false;
cout << "Not success, try again!";
cin >> humanInput;
}
else
cout << "Success" << '\n';
break;
}
} while (!(isHuman));
}
$ clang++-7 -Wall -o main main.cpp
main.cpp:23:39: warning: variable 'humanInputvalidator' is
uninitialized when used here [-Wuninitialized]
for (int humanInputvalidator; humanInputvalidator < hum...
^~~~~~~~~~~~~~~~~~~
main.cpp:23:37: note: initialize the variable 'humanInputvalidator' to
silence this warning
for (int humanInputvalidator; humanInputvalidator < hum...
^
= 0
1 warning generated.
So let's fix that.
Additionally, on the second iteration of getting input from the user, humanInputvalidator < humanInput.length() && isHuman will always be false. You'll want to reinitialize isHuman = true inside the do while loop.
Functions are a great way to simplify your code!
Use functions! It's a great way to simplify your code and decrease the number of variables in any single context.
bool isThisHumanInput(std::string data) {
for (int i = 0; i < data.length(); i++)
if (!(data[i] >= 48 && data[i] <= 57))
return false;
return true;
}
void botVarification()
{
string humanInput;
bool isHuman;
do {
cout << "Enter the number to verify that you are not a bot: ";
cin >> humanInput;
isHuman = isThisHumanInput(humanInput);
if (isHuman) {
cout << "Success" << '\n';
} else {
cout << "Not success, try again!\n";
}
} while (!isHuman);
}
There's several changes that are necessary to get this code functioning correctly. Here's one working version, with the functions and includes that you don't actually use yet removed and a typo corrected.
Highlights: We have to initialize humanInputvalidator, we have to reset isHuman to true at the beginning of the do-while loop, and the logic for exiting the inner for loop and printing "Success!" was all changed.
#include <iostream>
#include <string>
void botVerification();
int main()
{
botVerification();
return 0;
}
void botVerification()
{
std::string humanInput;
std::cout << "Enter the number to verify that you are not a bot: ";
std::getline(std::cin, humanInput); // getline to capture whitespace
bool isHuman;
do {
isHuman = true; // Reset to true at the beginning of each loop
// Initialize humanInputvalidator
for (int humanInputvalidator = 0; humanInputvalidator < humanInput.length() && isHuman; humanInputvalidator++) {
// Rewrite comparison using char literals for clarity
if (!(humanInput[humanInputvalidator] >= '0' && humanInput[humanInputvalidator] <= '9')) {
isHuman = false;
std::cout << "Not success, try again! ";
std::getline(std::cin, humanInput);
// No need to break since we test isHuman in the for loop
}
}
} while (!(isHuman));
// Print success after input is fully verified, not at some intermediate stage
std::cout << "Success!\n";
}
First of all, you need to initialize humanInputvalidator when you define it in the for loop. Variables in C++ do not have default values.
Also, in case you find an incorrect character in humanInput, you make the user input again. This happens while you are iterating over the characters in the string. This is not really good. In this particular case it does not break, but it may in some other one, so keep that in mind.
Moreover, in the for loop you alway break on the first iteration. Your break statement is just below the if-else and I think your intention was that it be inside the else branch.
All in all, I cannot pinpoint any specific reason for the infinite loop you are getting but these are at least a few things you can fix and then see what happens. I would also suggest to simplify your code and make it more readable, by splitting out the invalid input check to a separate function, like this:
bool isInputValid(const string& humanInput)
{
for (int humanInputvalidator = 0; humanInputvalidator < humanInput.length(); humanInputvalidator++) {
if (!(humanInput[humanInputvalidator] >= 48 && humanInput[humanInputvalidator] <= 57)) {
return false;
}
}
return true;
}
void botVarification()
{
string humanInput;
cout << "Enter the number to verify that you are not a bot: ";
cin >> humanInput;
do {
if (isInputValid(humanInput))
{
cout << "Success" << '\n';
break;
}
cout << "Not success, try again!";
cin >> humanInput;
} while (true);
}
The battleship program I wrote is supposed to loop a infinite amount of times until a condition is met. However it stops after the first execution. What is the matter with my loop? The code runs, however towards the end it outputs game over twice when its not supposed to. There are still more ships remaining in the game.
#include<iostream>
#include<fstream>
#include<string>
#include<cmath>
using namespace std;
bool FleetSunk();
void Fire(int&, int&, char&);
char ocean[25][25];
int main()
{
int x;
int y;
char spot;
ifstream input;
input.open("ocean.txt");
for(x=0;x<25;x++)
{
for(y=0;y<25;y++)
{
input >> ocean[x][y];
}
}
FleetSunk == false;
do
{
cout << "Please input x coordinate: ";
cin >> x;
cout << endl << "Please input y coordinate: ";
cin >> y;
cout<< endl;
Fire(x,y,spot);
FleetSunk();
}while(FleetSunk() == false);
}
void Fire(int& x, int&y, char&spot)
{
spot = ocean[x][y];
if(spot == '#')
{
cout << "You Have hit a ship"<< endl;
ocean[x][y] = 'H';
}
else if(spot == 'H')
{
cout << "HIT AGAIN" << endl;
}
else if(spot == '-')
{
cout << "MISS" << endl;
}
}
bool FleetSunk()
{
int m;
int n;
for(m=0;m < 25; m++)
{
for(n=0;n<25;n++)
{
if(ocean[m][n] == '#')
{
cout << "You still have ships remaining" << endl;
}
else
{
cout<< "You have hit all the ships. GAME OVER!" << endl;
return true;
}
}
}
}
Your FleetSunk function has two problems. One should have been a compiler warning, and one is a logical problem.
Firstly, not all paths in the function return a value... Technically. Although in your case that's not quite true because of the logic problem. Let me be more specific: If your entire board is populated with '#', and no shots are taken, then the function behaviour is undefined. It completes the loop and then does not return a value.
So now let's do the logic. You cannot know whether there are any un-hit ship locations until you have examined the entire board. That means you cannot exit from your inner loop in the way you are doing. How about instead you return false if you encounter an "alive" position, and return true at the end of the function (which is only reached if you never encounter an "alive" position).
bool FleetSunk()
{
for( int m = 0; m < 25; m++ )
{
for( int n = 0; n < 25; n++ )
{
if( ocean[m][n] == '#' ) return false;
}
}
return true;
}
See in the comments under your question for other suggestions related to how you are calling FleetSunk in your loop. I also recommend (as evident in my code example) that you don't write stuff to cout in a function that is testing for some condition. It's the responsibility of the caller to do that, not the function itself.
Finally, I would just like to say that the line FleetSunk == false; above your loop really does not do what you might think. That will take the function pointer, convert it to boolean and compare it with false. It's a crazy thing to do, and also useless because the resulting value isn't used for anything. Just delete that line.
I am writing a code that, for one or several lines of strings, find if the overall input has only "cool" (it's first middle and last string are the same) lines, only "uncool" lines or a mix of both.
The problem I'm having is whenever I input an even number the while loop terminates. Debugging I found that, just before jumping out n gets value 0 but I don't understand how this would make the loop end.
This is the code:
#include <iostream>
using namespace std;
int main () {
// Bool has control if we have found a cool line/non-cool line
bool cool = false;
bool uncool = false;
int n; //lenght of input
while (cin >> n) {
if (cool and uncool) break; // we have found one of each so we know it is a mixed input
else if (n%2 == 0) uncool = true; // if the lenght is even there is no middle string
else {
// we are trying to see if the middle and last string are equal to the first
string comparing_string;
cin >> comparing_string;
string rest_of_sequence;
bool this_is_cool = true;
for (int i = n-2; i >= 0; i--) { // we input the rest of strings and compare them to the first
cin >> rest_of_sequence;
if ((i == n/2 or i == 0) and rest_of_sequence != comparing_string) this_is_cool = false;
}
if (this_is_cool) cool = true;
else uncool = true;
}
}
if (cool and uncool) cout << "both types" << endl;
else if (cool and not uncool) cout << "all cool" << endl;
else if (uncool and not cool) cout << "none cool" << endl;
}
Any help is appreciated! I'm currently in first year of uni and always open to recommended books/webpages/videos to continue learning :)
The problem was that I thought the program would just ignore input that wasn't an integer in the while loop, but it doesn't.
Now the code is correct:
else if (n%2 == 0) {// if the lenght is even there is no middle string
uncool = true;
string just_passing_input;
for (int i = n; i > 0; i--) cin >> just_passing_input;
}
Thanks for the helpful feedback, I shall now continue learning.
So I've been trying to create this program that will take up to 12 digits from the user using string and string classes. The issue I'm having is:
Ignoring the (-) sign.
Ignoring the decimal point.
Giving an error when more than 12 digits are entered.
Only accepting digits (i.e no letters)
So far this is what I have:
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>
using namespace std;
bool test(char [] , int);
int main()
{
const int SIZE= 13;
char number[SIZE];
int count;
cout<< "Please enter a number up to "<< (SIZE-1) <<" digits long." << endl;
cout<< "The number may be positive or negative" << endl;
cout<< "and may include fractions (up to two decimal positions)" << endl;
cout<< "Sign and decimal dot(.) are not included in the digit count:"<< "\t";
cin.getline (number, SIZE);
if (test(number, SIZE))
{
while (number[count]!='\0')
{
cout<< "The currency value is: \t $";
cout<< setprecision(2) << number[count];
count++;
}
}
else
{
cout << "Invalid number: contains non-numeric digits.";
}
return 0;
}
bool test(char testNum[], int size)
{
int count;
for (count = 0; count< size; count++)
{
if(!isdigit(testNum[count]))
return false;
}
return true;
}
Any help is very much appreciated, but the most important to me at the moment is the 4th point. No matter what the input is, the output is "Invalid number:...." and I'm not sure why that is.
Your test function always test 13 chars even if the input is shorter.
Instead pass a string and use the range based for-loop so that you only test the valid chars - something like:
bool test(string testNum)
{
for (auto c : testNum)
{
if(!isdigit(c))
return false;
}
return true;
}
Further you should change your main-loop (where you print the value) as well, i.e. use string instead of char-array.
BTW - notice that this will only check for digits. Your description of the valid input format will require a more complex test-function.
For instance to check for sign you could add:
bool test(string testNum)
{
bool signAllowed = true;
for (auto c : testNum)
{
if (c == '-')
{
if (!signAllowed) return false;
}
else
{
if(!isdigit(c)) return false;
}
// Sign not allowed any more
signAllowed = false;
}
return true;
}
But you still need more code to check for the dot (.)
If you don't want to use a range-based for loop, you can do:
bool test(string testNum)
{
for (int i = 0; i < testNum.size(); i++)
{
if (testNum[i] == '-')
{
// Sign is only allowed as first char
if (i != 0) return false;
}
else
{
if(!isdigit(testNum[i])) return false;
}
}
return true;
}
I was writing a code for a counter. If I give 'a' as input, it should +1 the counter and show it on the screen. But when I do it, it shows 1 on the screen and the program ends. I want it to run until and unless i give some other character as input. What's the mistake I am making?
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int Counter = 0;
char t;
while(true)
{
t = cin.get();
if(t == 97)
{
Counter = Counter + 1;
}
else
break;
system("cls");
cout << Counter;
}
return 0;
}
The issue is when you are entering your 'a', you are probably hitting Enter as well, which is interpreted as another char. That second char is definitely not a, so your program breaks. This can be verified by just outputting what you read:
for (;;) {
std::cout << '?';
char t = std::cin.get();
std::cout << (int)t << '\n';
if (t != 'a') break;
}
std::cout << "done\n";
Which, when run, prints:
?a
97 // this is 'a'
?10 // this is '\n', note the additional ?
done
The simplest fix would be to use the input stream operator on cin, which would discard whitespace in the input (whereas get() does not):
char t;
for (;;) {
std::cout << '?';
std::cin >> t;
std::cout << (int)t << '\n';
if (t != 'a') break;
}
std::cout << "done\n";
Which, when run, produces:
?a
97
?b
98
done
which is what you'd intended.
Try this:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int Counter = 0;
char t;
while(true)
{
t = cin.get();
if(t == 97)
{
Counter = Counter + 1;
}
// else
// break;
system("cls");
cout << Counter;
}
//system("pause");
return 0;
}
Your else break; is the reason why you're closing after any interation. Basically after any iteration, it will break because due to any non-a input. However, running the code above, you will see the counter increment at every a input given and it will not break.
This will give you the basic operation you're looking for which is increment the counter based on input a, otherwise do nothing.
Edit: The above code will buffer your input and read it all, so if you have 5 a's like the following aaaaa, it will read it and output 5 for the counter.
If you want to break out of the loop, i suggest this:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int Counter = 0;
char t;
while(true)
{
cin >> t;
// t = cin.get();
if(t == 97)
{
Counter = Counter + 1;
}
else
break;
system("cls");
cout << Counter;
}
//system("pause");
return 0;
}
I tested it and it works. Seems to be with how cin.get() reads the buffered input from the console (i think). Not too sure on the specifics, but cin >> t does the trick.
Edit 2: Did some reading and i think cin.get() will consume the next character after your input, but in this case it is a newspace \n, which is why it will always break in your original code.