I need to get input from the user but if an invalid argument is passed in then the "Invalid" messages stack up.
I'd prefer if it just kept printing the invalid on the same line and then once a correct input is given it resets the line to original question.
I've seen the talk of using \r but it does not seem to work for me.
bool getInput(std::variant<std::string, float>* toOut, bool* restart, bool* qUsed){
std::string userIn;
std::cin >> userIn;
if(userIn == SENTINAL){
*restart = true;
return false;
}
try {
*toOut = std::stof(userIn);
} catch(std::invalid_argument) {
if(userIn == TO_SOLVE && !*qUsed){
*toOut = TO_SOLVE;
*qUsed = true;
} else {
std::cout << "\rInvalid, please try again : ";
getInput(toOut, restart, qUsed);
}
}
return true;
}
I haven't put the resetting to original question yet.
When I run this the \r does nothing.
Why is this / what's the best way to "update" cmd text?
Related
So, I've been trying to make this program this entire day and I got stuck at this big problem where I cannot it to log into the account by verifying with the previously existing data in my txt file of registered users.
NOTE: userEmail is inheritted from another class and is defined.
This is my login function:
void logIn() { // ! Function to log into an existing account.
system("cls");
string loginEmail, loginPassword;
bool verifyEmail = false;
cout<<"\n~\t~\tLogging into an existing account..\t~\t~\n";
cout<<"\nEmail: ";
cin.ignore();
getline(cin,loginEmail);
ifstream checkEmail("registeredUsers.txt");
ifstream open("registeredUsers.txt");
while(checkEmail>>userEmail && loginEmail.find('#') != string::npos && loginEmail.length() > 6) {
if (userEmail == loginEmail) {
verifyEmail = true;
}
else {
verifyEmail = false;
}
}
if (verifyEmail == true) {
cout<<"\nPassword: ";
getline(cin,loginPassword);
}
else {
cout<<"Email not found.. Please register a new account.\n";
system("pause");
return;
}
system("pause");
}
Lets say if my registeredAccounts.txt has lines
12345#gmail.com
testing#gmail.com
fortified#gmail.com
Then it would only ever continue to the password section if I typed fortified#gmail.com in my program and it would not let me proceed if i typed any other emails.
Break out of the while loop immediately after you set verifyEmail = true. There is no need to check additional email addresses if you have already found a match. As it is, your code goes on to check non-matching email addresses, setting verifyEmail back to false.
For example:
while(checkEmail>>userEmail && loginEmail.find('#') != string::npos && loginEmail.length() > 6) {
if (userEmail == loginEmail) {
verifyEmail = true;
break;
} else {
verifyEmail = false;
}
}
Now, you don't actually need to set verifyEmail to false. So you can just use:
while(checkEmail>>userEmail && loginEmail.find('#') != string::npos && loginEmail.length() > 6) {
if (userEmail == loginEmail) {
verifyEmail = true;
break;
}
}
I was wondering what I may have done wrong in writing this simple function which is supposed to return true if the given number is a prime, or false if not a prime.
bool isPrime(int num)
{
if (num <= 1)
{
status = false;
}
else
{
for (int i = 1; i <= num; i++)
{
if (num % i == 0)
{
dividers++;
}
}
if (dividers == 2)
{
status = true;
}
else
{
status = false;
}
}
return status;
}
Obviously, my main looks like this:
bool isPrime(int num);
bool status;
int dividers = 0;
int main() {
isPrime(2);
if (!isPrime)
{
std::cout << "Not prime" << std::endl;
}
else
{
std::cout << "Prime" << std::endl;
}
return 0;
}
I'm a C++ beginner and I'd really appreciate it if someone could help me there and correct my logic.
Have a good day:)
The immediate problem is in this two lines:
isPrime(2);
if (!isPrime)
The first line calls the function and discards the returned value. The second line converts a pointer to the function to bool. The output of your code does not depend on what you actually do in isPrime.
That is not how you call a function and use its result!
Instead you want
if (isPrime(2)) {
or
bool isP = isPrime(2);
if (isP) { ...
As mentioned in comments, there are also problems in the implementation of isPrime, but I hope this is enough to set you back on the right track.
PS: You should get rid of the global variable status. You do not need both, the return value and a global that stores the result, and if you can choose, you should definitely go for the return value.
I am having an issue trying to display correct debugging messages in my GUI on qt. I am implementing a binary tree based on words that are entered by a user. And for each word that is entered an appropriate debugging message should display.
For example:
user enters : a
then user enters b
debugging message word is greater than a
The problem that I am having is that if the user was to then type a third word in the debugging message is incorrect.
user enters c
debugging message still displays as word is greater than a
But I would like it to display word is greater than b instead.
If the user inputs a duplicate word the message should display 'word' has already been detected. This message only works if its the original word that the user has entered and is duplicating. For the example above if the user enters a again the correct message appears. If they enter b again the duplicate message does not appear.
How can I fix this?
QStringList tree::VerboseModeinsert(NodePtr &ptr, QString aWord)
{
aWord.remove(QRegExp("[[]"));
aWord.remove(QRegExp("[]]"));
if(!(aWord.contains(QRegExp("[0123456789]"))))
{
aWord = aWord.toLower();
if(ptr != NULL)
{
if(aWord < ptr->word)
{
insert(ptr->below, aWord);
QString a = "Word is less than ";
QString b = ptr->word;
verboseList << a + b;
}
else if(aWord > ptr->word)
{
insert(ptr->above, aWord);
QString a = "Word is greater than ";
QString b = ptr->word;
verboseList << a + b;
}
else
{
ptr->occurence++;
QString c = " has already been detected";
verboseList << aWord + c;
}
}
else
{
ptr = new WordTree;
ptr->word = aWord;
ptr->below = NULL;
ptr->above = NULL;
ptr->occurence = 1;
}
}
return verboseList;
}
Seems you forgot to update the pointer to the last inserted,
Try this:
...
if(aWord < ptr->word)
{
...
ptr = ptr->below;
}
else if(aWord > ptr->word)
{
...
ptr = ptr->above;
}
...
PS: I'm not completly sure what I'm doing beacause you don'n provide a MCVE, but I think the post is suficient to infer that you are not changing the pointer to the last inserted.
So im doing a sort Method using the bubble sort and compareTo method
Yet for some reason, when I run the program it compiles, does no errors whatsoever and shows a blinking cursor in the program (as if u are about to type something in; which u can, just when u press enter nothing happens) and this cursor keeps blinking.
What's wrong here ? (code based on teacher's instructions)
public static void sort(ArrayList al)
{
Person p,p1,p2;
String a1,a2;
boolean flag = true;
System.out.println("Database will be sorted acc to ID ");
System.out.println();
do
{
flag = false;
for (int i=0;i<al.size()-1;i++)
{
p = (Person)al.get(i);
a1=((Person)al.get(i)).personID;
a2=((Person)al.get(i+1)).personID;
if (a1.compareTo(a2) > 0){
p1= (Person)al.get(i);
p2 =(Person)al.get(i+1);
}
}
}
while (flag = true);
if (flag = false)
{
for (int i = 0; i < al.size(); i++)
{
p = (Person) al.get(i);
System.out.println("----------" + (i+1) + "-----------");
System.out.println("ID Number: "+ p.personID);
System.out.println("Name: "+ p.name);
System.out.println("Day of Birth: " +p.dayDOB);
System.out.println("Month of Birth: " +p.monthDOB);
System.out.println("Year of Birth: " +p.yearDOB);
System.out.println("Telephone Number: " +p.telNum);
System.out.println("");
}
}
The problem is in this loop:
do
{
....
}
while (flag = true);
You want to compare flag to true, i.e. flag == true, but instead you set flag to true with flag = true. Therefore, the loop will not exit, but instead run forever (or until you terminate the program).
You have the same problem in the following if statement.
I would ideally like to use one stack in this program but it doesn't let me. I keep getting a segment error 11. I got around this sort of by making a new vector and setting that equal to the first vector and then poping the new vector. But I eventually need to sync the popped vector up with the first vector but it throws a segment error 11.
anyway here is the code, its part of another project but I dont think the context is too important to know what its for. Also this does compile its just when I run this method it throws the error.
void print_well_formed_file(ifstream& ifs) {
vector<string> vec;
vector<string> finalVec;
string line;
string a;
string temp;
string final;
Lexer lexer;
Token tok;
while (getline(ifs, line)) {
lexer.set_input(line);
while (lexer.has_more_token()) {
tok = lexer.next_token();
switch (tok.type) {
case TAG:
if (tok.value[0] != '/'){
a = (tok.value);
if (a == "red") {
a = "\033[31m";
}
if (a == "green") {
a = "\033[32m";
}
if (a == "blue") {
a = "\033[34m";
}
if (a == "yellow") {
a = "\033[33m";
}
if (a == "magenta") {
a = "\033[31m";
}
if (a == "cyan") {
a = "\033[36m";
}
if (a == "dim") {
a = "\033[2m";
}
if (a == "underline") {
a = "\033[4m";
}
if (a == "bright") {
a = "\033[1m";
}
vec.push_back(a);
final = temp + a;
}
else{
string s;
string temp;
string fin;
finalVec = vec;
if(!finalVec.empty()){finalVec.pop_back();}
a = "\033[0m" + finalVec.back();
temp = final;
final = temp + a;
if(!vec.empty()){vec.pop_back();} // throws an error
vec = finalVec; // throws an error
}
break;
case IDENT:
a= (tok.value)+ " ";
temp = final;
final = temp + a;
break;
}
}
}
cout << final << endl;
}
You cannot pop or get an element from an empty vector. It's undefined behaviour, and it will likely crash your app.
You can verify that this is the problem by checking the length before each access in your code (you just "randomly" picked one of the locations in your latest update). Look, it's really simple.. just display an error message if it's empty.
if(!finalVec.empty()){finalVec.pop_back();}
a = "\033[0m" + finalVec.back(); // <-- bug
is obviously buggy: finalVec.back() may not exist: since the last element has just been popped the vector may be empty.