I'm writing a simple function that is supposed to read an input from a user as a string. Check if the strings solely consist of digits then converts it to and int and returns it. The problem is the loop never used regardless of the input. I'm struggling to find the root of the problem.
int correctInt()
{
string temp;
int input;
bool m;
do
{
m = false;
getline(cin, temp);
int length=temp.length();
for (int a = 0; a < length; a++)
{
if (temp[a] < '0' && temp[a]>'9')
{
cout << "ID should consist of numbers. Try again: ";
m = true;
break;
}
}
if (!m)
{
return input = atoi(temp.c_str());
}
} while (1);
}
Thank you in advance
You should use OR instead of AND:
temp[a] < '0' || temp[a]>'9'
Try to change && (and) condition to || (or) condition
if (temp[a] < '0' || temp[a]>'9')
Related
I am currently coding in C++ and am wanting only take notice of lowercase letters and numbers.
My problem is that when I enter a string containing integers and characters (such as a lowercase letter), does not return the correct answer for and ODD length (of the array) above the value of 3.
For instance, if I was to enter '1b1', it would return as a palindrome, otherwise if I were to write '1bbb1', it would return false.
Here is the code:
bool isPalindrome(string s){
int len = s.size();
int mid = len / 2;
int unsigned i;
stack<char> palindromeStack;
for (i = 0; i < mid; i++)
{
if(s[i] <= 47 && s[i] >= 58 ||
s[i] <= 96 && s[i] >= 123){
s.erase(i,1);
i--;
}
if (s[i] > 47 && s[i] < 58 ||
s[i] > 96 && s[i] < 123)
{
palindromeStack.push(s[i]);
}
if (len % 2 != 0)
{
i++;
}
}
while (s[i] != '\0')
{
char ele;
ele = palindromeStack.top();
palindromeStack.pop();
if (ele != s[i])
{
return false;
i++;
}
return true;
}}
I assume this has something to do with the IF statements in relation to the length of the array, but since I'm still quite new to programming, I am unable to find the solution.
Any help would be greatly appreciated! (this includes directing me to already answered questions that will solve my issue)
P.S. Code brackets were slightly modified to fit within the Stack Overflow Code Sample function.
Thanks
I have a much better code. Usage of any data structure template does not indicate that it is a good code. If your target is to check if a string is palindrome including alphanumeric characters please refer to the following code. I have shared the screenshots as an example :-
#include <iostream>
#include<string>
using namespace std;
string transform(string s)
{
string result = "";
for(char ch : s)
{
if(('a'<=ch && ch<='z') || ('0'<=ch && ch<='9') )
result += ch;
}
return result;
}
int main() {
string s="";
// reading the input from the std input
cin>>s;
s = transform(s);
bool isPalindrome = true;
for(int i = 0, j = s.size()-1; i<=j; i++,j--)
{
if(s[i]!=s[j])
{
isPalindrome = false;
break;
}
}
if(isPalindrome)
{
cout<<"Palindrome";
}
else
{
cout<<"Not Palindrome";
}
return 0;
}
The key point is it won't be a palindrome if the values are not same from both ends of the string. If any character is unequal it is proven that it is not a palindrome, hence we need not to go for other comparisons.
This has lesser lines of code and works in every scenario.
This code will bail out checking at first sign of a mismatch :
#include <cassert>
#include <string>
bool is_palindrome(const std::string& str)
{
for (int front = 0, back = static_cast<int>(str.length()) - 1; front < back; ++front, --back)
{
if (str[front] != str[back]) return false;
}
return true;
}
int main()
{
assert(is_palindrome(""));
assert(is_palindrome("1"));
assert(is_palindrome("121"));
assert(is_palindrome("abcdefedcba"));
assert(!is_palindrome("121abc"));
return 0;
}
Edit (now with iterator & reverse iterator):
bool is_palindrome(const std::string& str)
{
for (auto [front, back] = std::tuple{str.begin(), str.rbegin()}; front < back.base(); ++front, ++back)
{
if (*front != *back) return false;
}
return true;
}
#include <iostream>
using namespace std;
int main() {
char a[101]{0};
cin>>a;
cin.getline(a,101);
cin.ignore();
int currLen{0};
int maxLen{0};
int startInd{-1};
int endInd{-1};
for(int i=0; i<101; i++) {
if(a[i]!=' ' ) {
++currLen;
} else if(a[i]==' '||a[i]=='\0') {
if(currLen>maxLen) {
maxLen=currLen;
startInd=i-currLen;
endInd=i-1;
}
if(a[i]=='\0')
break;
currLen=0;
}
}
cout<<maxLen<<endl;
if(startInd==-1)
cout<<-1;
else
for(int i=startInd; i<=endInd; i++)
cout<<a[i];
return 0;
}
If I take an input here, for example, "My name is Manav Kampani"
It will output 5
Manav instead of 7
Kampani
But if I write "My name is Manav Kampani ", with space after the last word
than it is considering Kampani too printing Kampani.
Also when I input "Kampani Manav is my name" then too it's displaying the wrong output. That means it is not considering the first word of the sentence.
if(a[i]!=' ' )
{
++currLen;
}
else if(a[i]==' '||a[i]=='\0')
{
....
}
Consider the case of a[i] == 0. Which of these if-statements will apply.
Answer: the first one. Which means you'll never look at the final word in the string. You also don't exit at the end of the string, but instead loop through whatever is in your string all the way out to character 101.
As a general structure, be very, very careful with this:
if (condition)
else if (condition)
// without a final else section
If you do that, you need to think about what you're doing. In this particular case, you can have:
if (a[i] != 0 && a[i] != ' ')
else
It may not solve all your issues, but it should solve some.
A nice sliding window pattern implementation.
You have 3 problems in your code
You must not write cin >> a;
You must not write cin.ignore();
You need to modify your if statement like so: if (a[i] != ' ' && a[i] != '\0') Otherwise you will not detect the last word.
Your complete working code with that minor fixes will lokk like that.
int main()
{
char a[101]{ 0 };
//cin >> a;
cin.getline(a, 101);
//cin.ignore();
int currLen{ 0 };
int maxLen{ 0 };
int startInd{ -1 };
int endInd{ -1 };
for (int i = 0; i < 101; i++)
{
if (a[i] != ' ' && a[i] != '\0')// Add comparison
{
++currLen;
}
else if (a[i] == ' ' || a[i] == '\0')
{
if (currLen > maxLen)
{
maxLen = currLen;
startInd = i - currLen;
endInd = i - 1;
}
if (a[i] == '\0')
break;
currLen = 0;
}
}
cout << maxLen << endl;
if (startInd == -1)
cout << -1;
else
for (int i = startInd; i <= endInd; i++)
cout << a[i];
return 0;
}
Additionally. You should not use C-Style arrays in C++. And please use std::string
There is a couple of things here:
1- You don't need to do a cin>>a this is actually consuming the first word, and afterwards the content is overrided by cin.getline(). So removing the firsst cin>>ayou'll be fine.
2- The last word is not read because there isn't any if condition that matches the condition aka.
if(a[i]!=' ' ) case of not a space
//not end of word
else if(a[i]==' '||a[i]=='\0') case of space or null
//end of word
So your last character is not a space nor null, that means you don't detect the last word.
The code will get two string from user and checks the string , includes substring as the second input or not.
string st1;
string subst1;
string message = " ";
cout << "Enter string and subst:";
cin >> st1;
cin >> subst1;
for (int a=0; a < st1.length(); a++) {
if (st1[a] == subst1[0]) {
for (int k = 0; k < subst1.length(); k++) {
if (st1[a + k] == subst1[k])
message = "True";
else
message = "False";
}
}
}
cout << message;
This code does not work inputs like "alice" and "ba". The output should be false but when I execute the code program directly ended
Because in some cases a + k exceeds the length of the string st1:
if (st1[a + k] == subst1[k]) {
message = "True";
}
before executing this statement, verify if a + k < st1.length()
but another remark:
when message becomes False you must stop comparison else the variable message might be again True.
Why not use find():
string st1, subst1, message=" ";
cout<<"Enter string and subst:";
cin>>st1>>subst1;
if (st1.find(subst)==string::npos)
message="Not found";
else message ="Found";
If you're not allowed to use this approach, then I propose you the following:
string st1, subst1, message=" ";
bool found=false;
cout<<"Enter string and subst:";
cin>>st1 >>subst1;
for (int a=0; !found && a<st1.length();a++) {
if (st1[a]==subst1[0]) {
found = true; // there's some hope
for (int k=0; found && k<subst1.length(); k++) {
if (a+k>=st1.length() || st1[a+k]!=subst1[k]) // oops! might overflow or fail
found = false; // this will also end the inner loop
}
}
}
message = found ? "True":"False";
cout<< message<<endl;
The principle is that for a compare to be successfull, all chars must be equal. But if a single char fails, you shall stop the failed comparison.
Here a live demo
Hello I am trying to do a programming assignment that converts a binary number to a decimal. The problem states that I have to get the users input as a sting and if there is anything other than a 1 or a 0 in the users input it should give an error message then prompt them to give a new input. I have been trying for a while now and I cant seem to get it right can anyone help me?
so far this is my best attempt it will run every input of the string into a if statement but it only seems to care about the last digit i cant think of a way to make it so if there is a single error it will keep while loop statement as true to keep going.
#include <iostream>
#include <string>
using namespace std;
string a;
int input();
int main()
{
input();
int stop;
cin >> stop;
return 0;
}
int input()
{
int x, count, repeat = 0;
while (repeat == 0)
{
cout << "Enter a string representing a binary number => ";
cin >> a;
count = a.length();
for (x = 0; x < count; x++)
{
if (a[x] >= '0' &&a[x] <= '1')
{
repeat = 1;
}
else
repeat = 0;
}
}
return 0;
}
return 0;
}
Change your for loop as this:
count = a.length();
repeat = 1;
for (x = 0; x < count; x++)
{
if (a[x] != '0' && a[x] != '1')
{
repeat = 0;
break;
}
}
The idea is that repeat is assumed to be 1 at first (so you assume that your input is valid). Later on, if any of your input characters is not a 0 or 1, then you set repeat to 0 and exit the loop (there's no need to keep looking for another character)
I know that I can check if a "word" is all letters by:
bool checkAlpha(string str){
bool retVal;
for(int i = 0; i < str.size(); i++){
if(isalpha(str[i]) == 0){
retVal = true;
cout << "Input must only contain letters\n";
break;
}
else{
retVal = false;
cout << "all good\n";
}
}
return retVal;
}
Because of how I use the function return value, I need it to return TRUE if it is NOT all letters, and FALSE if it IS all letters. There's probably an easier way to do this but I just started C++ so this works for my current purpose.
My question is how do I check if a string is multiple "words"? When it reaches a space the function (correctly) says the space is not an alpha and tells me the input must only be letters. I tried doing
if((isalpha(str[i]) != 0) || (str[i] == " "))
and changing the "if" to return false (input only letters & space) and "else" to return true, but when I tried this I got a compiler error:
ISO C++ forbids comparison between pointer and integer [ -fpermissive]
So what can I do to get that a string of user input is only letters or space? (Preferably the simplest method)
This statement:
str[i] == " "
Is incorrect, it should be:
str[i] == ' '
but even better
isspace( str[i] )
as your condition does not check for other symbols like tab etc.
Also you have break in logic, in case you meet not alpha and not space you can set retVal to true (and also should terminate loop as you already got the answer), but you cannot set it to false otherwise. So your corrected code could be:
bool checkAlpha(const string &str){
bool retVal = false;
for(int i = 0; i < str.size(); i++){
if( !isalpha(str[i]) || !isspace(str[i]){
retVal = true;
cout << "Input must only contain letters\n";
break;
}
}
if( !retval )
cout << "all good\n";
return retVal;
}
if you do not need to provide diagnostic messages, function can be as simple as:
bool checkAlpha(const string &str){
for(int i = 0; i < str.size(); i++)
if( !isalpha(str[i]) || !isspace(str[i])
return true;
return false;
}
And your function name is confusing, based on return values it should be called checkNotAlpha
I guess it should be enought to fix it as follows:
if((isalpha(str[i]) != 0) || (str[i] == ' '))