Program returning blinking Cursor - bubble-sort

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.

Related

vector, removing object trouble

I am new to c++ and am currently learning sfml.
I have set up a system that adds one 'Snowpile' object to the vector. But when I keep hitting errors like "can't increment vector past iterator past end" or that it's outside the scope.
std::vector<Snowpile*> snowpiles;
I want it to check every snowpile for the removed2 bool, and delete the ones that do have it.
for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); s_it++) {
int sindex = std::distance(snowpiles.begin(), s_it);
if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == false) {
snowpiles[sindex]->melting = true;
}
else if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
snowpiles[sindex]->melting = true;
}
else if (!snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
snowpiles[sindex]->melting = false;
}
snowpiles[sindex]->meltedrem(sindex, snowpiles, m_win);
if (snowpiles[sindex]->removed2 == true)
{
cout << "Detected removed 2 at " << sindex << endl;
//delete snowpiles[sindex];
snowpiles.erase(snowpiles.begin() + sindex - 1);
}
}
The melting parts determine whether the player is on top of a snowpile. The meltdrem functions checks for bool 'melting' == true and then proceeds to start the timer. After a few seconds (+ animations) it sets the bool removed2 to true.
I know that at the program at least sees the bools changing, so thats not it.
Am I simply using vector wrong, or do I need to change something in my loop?
The loop is located in the while(window.isOpen()) loop in int main.
For starters it is unclear why there is used the expression
snowpiles.erase(snowpiles.begin() + sindex - 1);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
instead of
snowpiles.erase(snowpiles.begin() + sindex);
^^^^^^^^^^^^^^^^^^^^^^^^^^
if in a comment you wrote
//delete snowpiles[sindex];
You need to increase the iterator in the for loop only when a current object was not removed.
Change the loop the following way
for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); ) {
//...
if (snowpiles[sindex]->removed2 == true)
{
cout << "Detected removed 2 at " << sindex << endl;
//delete snowpiles[sindex];
s_it = snowpiles.erase( s_it );
}
else
{
++s_it;
}
}

C++ boolean infinite loop

so I've got this code:
bool toggl = false;
while (!GetAsyncKeyState(VK_END)) {
if (GetAsyncKeyState(VK_INSERT)) {
if (toggl) {
toggl = false;
std::cout << "Off" << std::endl;
}
else {
toggl = true;
std::cout << "On" << std::endl;
}
}
}
The problem is whenever I click insert it just creates a infinite loop changing from false to true. When I use break my whole window just closes.
Any help appreciated.
Thanks,
Ossie
From the documentation for GetAsyncKeyState: "If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState."
hi lo
1000 0000 0000 0001
^ ^
| |
| pressed since last call
key down (0 for up)
For the infinite loop you only need to have the key state be non-zero. Better tests...
0 != (GetAsyncKeyState(VK_INSERT) & 1) // pressed since last call
0 != (GetAsyncKeyState(VK_INSERT) & 0x8000) // key down
The same documentation warns about use of this last bit for mouse clicks and when other processes are using GetAsyncKeyState at the same time. Worth reading.
Current URL to documentation: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate
The problem is that when insert is tapped, your program will have looped on GetAsyncKeyState 20 or 30 times. And then your toggl flag is getting flipped each time. Hence, a new print statement.
I suspect this is what you really want:
bool toggl = false;
while (!GetAsyncKeyState(VK_END)) {
bool isInsertDown = (GetAsyncKeyState(VK_INSERT) != 0);
if (toggl && !isInsertDown)
{
toggl = false;
std::cout << "Off" << std::endl;
}
else if (!toggl && isInsertDown)
{
toggl = true;
std::cout << "On" << std::endl;
}
}
The above will flip the togl state to true when the insert key is down, and set it back to false when you lift your finger off the key.
But if you want to have toggl state changed on individual key presses. That is, first insert tap sets toggl to true and the next key press sets it back to false, then you'll need another variable. Hence:
bool toggl = false;
bool lastWasDown = false;
while (!GetAsyncKeyState(VK_END)) {
bool isInsertDown = GetAsyncKeyState(VK_INSERT) != 0;
if (isInsertDown == lastWasDown) {
continue;
}
if (isInsertDown && !toggl) {
toggl = true;
std::cout << "On" << std::endl;
}
else if (isInsertDown && toggl) {
toggl = false;
std::cout << "Off" << std::endl;
}
lastWasDown = isInsertDown;
}

QT printing binary tree instruction messages

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.

C++ returning bool is always false?

I implemented a Quiz Code and did a short change at the end of it to check if the User answered it correctly.
My if / else looks like this:
if (answer == rightanswer){
rightA = true;
}
else {
rightA = false;
}
return rightA;
I already checked with the debugger that if the correct answer is entered it goes to rightA = true; and to return, so this works finde.
But if i check the value of rightA it's false.
If it's needed, here is the function that i use to call the Quiz:
void gameOver(char field[HEIGHT][WIDTH], char newField[HEIGHT][WIDTH]){ // TODO
bool rightA = false;
showQuizDialog(rightA);
do{
system("cmd /c cls");
switch (rightA){
case true : cout << "menu"; menu(field, newField); break;
case false : showQuizDialog(rightA); break;
default : cout << " ";
}
}while(rightA == false);
}
I'm a bit hintless. I may have some logic failure in it i just don't see at the moment.
Greetings
E: I don't wanted to bomb you guys with code. But here is it:
bool showQuizDialog(bool rightA){
Quiz* quiz = Quiz::getInstance();
quiz -> askQuestion(rightA);
return rightA;
}
And the full askQuestion:
bool Quiz::askQuestion(bool rightA) {
int fragenID = rand() % this->fragen.size(); //zufällige Fragen auswählen
struct Question frage = this->fragen.at(fragenID);
std::cout << frage.frage.c_str() << std::endl << endl; //Frage stellen
int rightanswer = this->listAnswers(frage.antworten);
int answer = this->readAnswer(0, frage.antworten.size() - 1);
if (answer == rightanswer){
rightA = true;
}
else {
rightA = false;
}
return rightA;
}
Is showQuizDialog(rightA) supposed to magically change the value of rightA? (I'm assuming you're not passing it by reference).
Did you mean to write rightA = showQuizDialog(rightA) or rightA = quiz -> askQuestion(rightA)?
Also, in your switch that switches on a bool, do you expect any other values than a true or a false?
Your showQuizDIalog is a call-by-value function. So always store the return value of the function into rightA, when calling showQuizDialog, that is :
rightA = showQuizDialog(rightA);
Otherwise, change your function declaration to allow pass-by-reference, maybe like this
showQuizDialog(&rightA);
and no need to return anything from the function(just use a pointer instead of a variable rightA inside the function)

Nested for loop being ignored after if-else chain

I am programming a MARIE assembler for one of my classes and I've ran into a logical error involving my control structure for one of my functions.
What I'm trying to accomplish is taking in all the data that was inserted into my vectors and then that data is being used to create integer opcode data for display. Yet for whatever reason my nested for loop is being ignored after my if-else chain.
The code within the nested for-loop seems to be working properly aside from this one logic error.
Please note that instructions, hexNums, secondPassData, valueZ, and symBols are my vectors.
For some clarification:
The If-Else chain is just used to read instruction words and to set basedInt to the proper decimal number for later hexadecimal conversion.
There are a few special conditions in the code below which are marked.
If there is no special condition then the code checks the valueZ vector at instructions.at(i) to see if the valueZ element is in symBols.
If it is a symBol element through character checks, it takes its hexNums position and adds it to the basedInt.
If it is not, it instead has its corresponding valueZ element converted from string to int and then added to the basedInt.
Those elements are added to the secondPassData vector.
int basedInt;
int newInt;
int pushInt;
string temp;
for(unsigned int i = 0; i < instructions.size(); ++i) //if i is less then instructions.size(), follow through with the statement
{
if(instructions.at(i) == "JNS") //sets basedInt to a decimal version of its hexidecimal opcode
{
basedInt = 0;
}
else if(instructions.at(i) == "HALT") //a special condition where the number is plugged into the secondPassData vector automatically
{
secondPassData.push_back(28672);
continue;
}
else if(instructions.at(i) == "CLEAR") //same as above
{
secondPassData.push_back(-24576);
continue;
}
else if(instructions.at(i) == "ADDL")
else if(instructions.at(i) == "ORG")
{
secondPassData.push_back(0000);
continue;
}
else if(instructions.at(i) == "HEX") //checks for the HEX psuedo-OP.
{
temp = valueZ.at(i); //converts it at position i to a string
basedInt = atoi(temp.c_str()); //converts that string to an int.
secondPassData.push_back(basedInt);//pushes into vector.
continue;
}
else if(instructions.at(i) == "DEC")
{
temp = valueZ.at(i);
basedInt = atoi(temp.c_str()); //similar function as above.
secondPassData.push_back(basedInt);
continue;
}
else
{
cout << "Beep Boop, program borked!" << endl;
return;
}
//for some reason the code below is getting ignored.
cout << i << endl;
for(unsigned int a = 0; a < instructions.size(); ++a) //works
{
cout << i << " " << a << endl;
string valFind = valueZ.at(i);
string symFind = symBols.at(a); //works
temp = valueZ.at(i);
if(symFind[0] == valFind[0])
{
newInt = hexNums.at(a);
pushInt = basedInt + newInt;
secondPassData.push_back(pushInt);
break;
}
else if(symFind[0] != valFind[0]) //works
{
temp = valueZ.at(i);
newInt = atoi(temp.c_str()); //works
pushInt= basedInt + newInt;
secondPassData.push_back(pushInt); //works
break;
}
break;
}
}
If you hit a continue in your else-if chain your main for loop will jump to its next iteration and will skip the rest of your code (in this case your nested for loop)
continue