首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当出现问题时,"linked-list“控制台应用程序会冻结,但仍然不会显示错误,所以我无法确定问题所在

当出现问题时,"linked-list“控制台应用程序会冻结,但仍然不会显示错误,所以我无法确定问题所在
EN

Stack Overflow用户
提问于 2020-11-10 01:59:42
回答 1查看 24关注 0票数 0

对于上下文,我已经创建了一个基本的“电子邮件模拟器”,您可以使用它向自己发送电子邮件、阅读电子邮件和删除电子邮件。在这个方法中,我必须使用堆栈链表样式的方法,这是标准。

到目前为止,我发现问题出在displayInbox函数上,但我不确定到底出了什么问题,因为从我所掌握的知识来看,它似乎是可以工作的。然而,我不能确定,因为它没有提供错误代码或触发本地Windows调试器,它只是冻结。

要触发与我相同的错误,只需编写两封电子邮件,然后检查收件箱。如果你在两者之间检查收件箱,这并不重要。我以前可以这样做,但现在不行了,我正在使用VS2019作为参考。

我没有太多的经验,所以它可能会非常臃肿,所以它相当大。但是我尽了最大的努力把它从600多行缩短到280行左右,但是你仍然可以让错误发生。这是case https://pastebin.com/Hp3uP0B9中完整程序的粘贴链接

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <stdlib.h> 
#include <windows.h> 
using namespace std;

struct Email //just a basic struct
{   
    string data;
    
    int index{}; //every new email will have a different index, used to traverse and pinpoint the correct email.

    Email* prev{}, * next{}; //just previous and next nodes
};
Email* myTemplate() //used to initialise a struct (alternative of constructor)
{
    Email* temp = new Email;

    temp->data = "\0";

    temp->index = 0;
    temp->next = NULL;
    temp->prev = NULL;

    return temp;
};

struct UI //another basic struct, but using constructors
{
    UI* prev, * next; //previous and next nodes
    string text[2]; //stores the selected text and unselected text

    bool selected; //bool to know when to trigger selected text
    int menuFunc; //used to determine which function to call, can also be used to represent Email's index when passing in values

    UI()
    {
        prev = NULL;
        next = NULL;
        text[0] = "\0";
        text[1] = "\0";
        selected = false;
        menuFunc = -1;
    }
    UI(UI* myPrev, UI* myNext, int myMFunc, string myText)
    {
        prev = myPrev;
        next = myNext;
        menuFunc = myMFunc;
        text[0] = myText;
        text[1] = "<<" + text[0] + ">>";
        selected = false;
    }
};

int mainMenu()
{
    int temp;
    cout << "type 1 to compose email, type 2 to display inbox, type 99 to quit\n: ";
    cin >> temp;
    if (temp == 1||temp == 2||temp == 99)
    {
        return temp;
    }
    else
    {
        return mainMenu();
    }   
}

int getKeyInt() //just a function to get relevant key codes
{
    if (GetAsyncKeyState(VK_UP))
    {
        return VK_UP;
    }
    else if (GetAsyncKeyState(VK_DOWN))
    {
        return VK_DOWN;
    }
    else if (GetAsyncKeyState(VK_RETURN))
    {
        return VK_RETURN;
    }
    else if (GetAsyncKeyState(VK_ESCAPE))
    {
        return VK_ESCAPE;
    }
    else
    {
        return -1;
    }
}

void displayInbox(UI* myNavi, UI* myHead, UI* myTail, Email*& eNavi, Email*& eHead, Email*& eTail) //displays the inbox of the mail
{
    bool modified = false;
    bool tempRunFlag = true;
    int tempKeyPress;

    UI* refreshCache = myHead; // to log the navigator's location upon reprinting the screen, points to head before the loop begins

    myNavi = myHead; //points the navigator to the newest node in the list

    eNavi = eTail; //email navigator switches address to the newest node in the email linked list

    if (eNavi->data != "\0") //to check if newest mail has values, just in case
    {
        myNavi->menuFunc = eNavi->index; //assigns the email index to the "menuFunc" to be passed when calling deleteMail() and displayMail()
        myNavi->text[0] = eNavi->data;  //sets the UI text of navigator
        myNavi->text[1] = "<<" + myNavi->text[0] + ">>";
        myHead = myNavi;//setting myHead to point to navigator's current address
        myHead->selected = true; //this will trigger the selected text's output later
        refreshCache = myHead;// assigns refreshCache to myHead
        myTail = myHead; //if it's only 1 mail in the list, then this will prevent UI from traversing into NULL, if not, below will change the values

        if (eNavi->prev != NULL)//if email navigator has a earlier mail to point to, false if there's only 1 element in the list, which is already done above
        {
            while (eNavi != NULL)//if email navigator is not pointing to the earliest mail, or if theres only 1 element
            {
                if (eNavi != eHead) //double checking if email navigator hasn't reached the earliest mail yet, if it is, then no need to go even earlier
                {
                    eNavi = eNavi->prev; //email navigator approaches eHead by 1 node
                }
                myNavi->next = new UI(myNavi, NULL, eNavi->index, eNavi->data); //creates a new node to point to 
                myNavi = myNavi->next; // navigator switch to the next address that it created
                myTail = myNavi; //assigns tail to newly created UI navigator node
            }
        }
    }
    else //if newest mail has no values, or no mail
    {
        myHead = new UI(NULL, NULL, 0, "nothing to see here");
        myHead->selected = true;
        refreshCache = myHead;
        myTail = myHead;
    }

    while (tempRunFlag)
    {
        system("CLS");
        cout <<
            "\nNow browsing inbox..." << endl <<
            "____________________________________________________________________________________________________" << endl <<
            "MAIL DATA"<< endl;
        myNavi = myHead; //UI navigator will be reassigned to point to first UI
        while (myNavi != NULL)
        {
            cout << myNavi->text[(int)myNavi->selected] << endl;
            myNavi = myNavi->next;
        }
        myNavi = refreshCache;//similar implementation in the prompt() function;
        if (myNavi != NULL)
        {
            cout << "\nMenu Function code: " << myNavi->menuFunc << endl;//used for debugging, displays the menuFunc
        }
        cout <<
            "\n\nReached end of inbox" << endl <<
            "____________________________________________________________________________________________________" << endl <<
            "[Use ARROW KEYS UP & DOWN to navigate, ESC to return to Main Menu]" << endl;
        system("pause");

        tempKeyPress = getKeyInt();

        switch (tempKeyPress)
        {
        case VK_UP:
            if (myNavi != myHead)
            {
                myNavi->selected = false;
                myNavi = myNavi->prev;
                myNavi->selected = true;
                refreshCache = myNavi;
            }
            break;
        case VK_DOWN:
            if (myNavi != myTail)
            {
                myNavi->selected = false;
                myNavi = myNavi->next;
                myNavi->selected = true;
                refreshCache = myNavi;
            }
            break;
        case VK_ESCAPE:
            tempRunFlag = false;
            break;
        default:
            break;
        }
    }
    return;
}

void composeEmail(Email*& eHead, Email*& eTail) //prompting the user to get data
{
    Email* draft = new Email;
    system("CLS");
    if (eHead->data != "\0") ///used to get rid of a \n character in the buffer for no reason, I don't know why it's there, but whats weird is that it only happens once the email linked list already has 1 element inside of it
    {
        cin.ignore();
    }
    do
    {
        cout << "\nPlease type in data (16 character limit)" << endl; //just for no reason
        getline(cin, draft->data);
    } while (draft->data.length() > 16 || draft->data.length() <= 0);
    while (draft->data.length() < 16)
    {
        draft->data += " ";
    }
    cout << "\n\nEmail is sent! Please check inbox." << endl;

    draft->next = NULL;
    if (eHead->data == "\0") //if current head node is empty
    {
        draft->prev = NULL;
        draft->index = eTail->index + 1;
        eHead = draft;
        eTail = eHead;
    }
    else //if head node already has a value
    {
        draft->prev = eTail;
        draft->index = eTail->index + 1;
        eTail->next = draft;
        eTail = draft;
    }

    system("pause");
}

bool mainMenuExecute(int executionCode, UI* uiNaviIB, UI* uiHeadIB, UI* uiTailIB, Email*& eNavi, Email*& eHead, Email*& eTail)
{
    if (executionCode == 1)
    {
        composeEmail(eHead, eTail);
        return true;
    }
    else if (executionCode == 2)
    {
        displayInbox(uiNaviIB, uiHeadIB, uiTailIB, eNavi, eHead, eTail);
        return true;
    }
    else if (executionCode == 99)
    {
        return false;
    }
}

int main()
{
    //Inbox UI
    UI* uiHeadIB = new UI(NULL, NULL, 0, "nothing to see here"),
        * uiTailIB = uiHeadIB,
        * uiNaviIB = uiHeadIB;
    uiNaviIB->selected = true;

    //Actual mail stuff
    Email* mHead = myTemplate(),
        * mTail = mHead;
    Email* mNavi = mHead;

    bool simulate = true;

    while (simulate)
    {
        system("CLS");
        simulate = mainMenuExecute(mainMenu(), uiNaviIB, uiHeadIB, uiTailIB, mNavi, mHead, mTail);
    }
}

希望当我学到更多东西时,有人能提供建设性的批评,干杯。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-10 05:01:35

我解决了这个问题,但是还有另一个问题,但是这是另一个问题,至于我是如何解决它的,我在if(eNavi!= eHead)后面放了一个else{ break ;},因为它会导致while循环在没有中断的情况下无限循环。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64756856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档