Возникли досадные проблемы с буфером cin - PullRequest
0 голосов
/ 03 марта 2019

Вот мой кусочек кода.По сути, я передаю пользователя в это меню выбора.Когда пользователь делает выбор, я возвращаюсь к main, а затем передаю их соответствующему классу для выполнения дальнейших функций.

Например, когда пользователь выбирает «send», они передаются на main изатем передается в функцию, которая собирает информацию о том, куда отправлять.Затем вернитесь к основному, затем вернитесь к функции, которая спрашивает их, сколько.Это работает отлично с первого раза.

Проблема в том, что, если они пытаются отправить другую транзакцию, он автоматически заполняет адрес суммой, введенной ранее.Пользователь должен удалить его самостоятельно из строки консоли.По сути, сумма застревает в буфере cin и автоматически заполняет переменную.Я пытался использовать getline, и у него та же проблема.Я могу использовать небольшую функцию для очистки буфера cin с помощью cin.clear () и cin.ignore (1000, '\ n'), и это решает мою проблему, но затем пользователь должен нажать ввод дополнительного времени после ввода.

Я изолировал проблему с меню.Когда я исключаю меню из моей программы, проблема исчезает.Меню находится в стадии разработки, я знаю, что оно не красивое и не отполированное.Я не могу понять, почему он это делает, хотя.Пожалуйста, помогите, я собираюсь вырвать мои волосы.

Кроме того, проблема не в части кода if (refresh) {...}, я пытался исключить это ипроблема сохраняется.

файл заголовка меню содержит только некоторые частные переменные и векторные объявления.Я буду рад выслать дополнительный код по запросу.

menu.cpp

#include "menu.h"
#include "KMD_COMMANDS.h"
#include <windows.h>

std::string menu::userInterface()
{
    KMD_COMMANDS displayInfo;

    bool selecting = true;  //
    refresh = true;         //
    numRight = 3;           //reset variables back to default
    options = oDWB;         // < string vector

    system("cls");

    hideCursor();
    while(selecting)
    {
        numLeft = 3 - numRight;     //sets the number of left movements available

        if(refresh)   //only refresh the screen when user makes an input. I plan to use a console vector updating method in the future instead of "cls"... I know "cls" sucks
        {
            system("cls");

            std::cout << "Balance: ";
            displayInfo.getBalance();
            std::cout<<std::endl;
            std::cout << "Public Address: ";
            displayInfo.getPubKey();
            std::cout<<std::endl;

            for(int i = 0; i < options.size(); i++)
            {
                std::cout << options[i];
            }

            refresh = false;    //refresh is done
        }

        Sleep(100);     //this makes a delay so inputs are less sensitive

        if(GetAsyncKeyState(VK_RIGHT))
        {
            refresh = true;     //reset refresh variable so console updates

            switch(numRight)    //moves the selector around
            {
                case 1:
                    numRight--;
                    options = optionsDefault;   //sets the options selector
                    options[12] = "[";          //back to default state
                    options[14] = "]";          //and moves brackets
                    break;
                case 2:
                    numRight--;
                    options = optionsDefault;
                    options[8] = "[";
                    options[10] = "]";
                    break;
                case 3:
                    numRight--;
                    options = optionsDefault;
                    options[4] = "[";
                    options[6] = "]";
                    break;
                default:
                    break;
            }
        }

        if(GetAsyncKeyState(VK_LEFT))    //moves the selector around
        {
            refresh = true;

            switch(numLeft)
            {
                case 1:
                    numRight++;
                    options = optionsDefault;
                    options[0] = "[";
                    options[2] = "]";
                    break;
                case 2:
                    numRight++;
                    options = optionsDefault;
                    options[4] = "[";
                    options[6] = "]";
                    break;
                case 3:
                    numRight++;
                    options = optionsDefault;
                    options[8] = "[";
                    options[10] = "]";
                    break;
                default:
                    break;
            }
        }

        if(GetAsyncKeyState(VK_UP))     //takes users selection (changed to up for debugging purposes)
        {
            switch(numRight)    //takes selection choice based from number of right inputs remaining
            {
                case 1:
                    userChoice = "send";
                    return userChoice;
                    break;
                case 2:
                    userChoice = "unlock";
                    return userChoice;
                    break;
                case 3:
                    userChoice = "lock";
                    return userChoice;
                    break;
                default:
                    userChoice = "quit";
                    return userChoice;
                    break;
            }
        }
    }
}

Здесь пользователь передается для сбора информации, где расположены сундуки:

#include "confirmSend.h"

#include <iostream>
#include <windows.h>

std::string confirmSend::sendToAddress()
{
    Sleep(100);     //delay so user doesn't accidentally input twice

    bool confirm = false;
    std::string addressInput;
    while(!confirm)
    {
        //std::cin.clear();
       // std::cin.ignore(1000,'\n');

        system("cls");
        std::cout << "Type cancel to cancel..." << std::endl;
        std::cout<<std::endl;
        std::cout << "Enter the address of where to send: ";
        std::cin >> addressInput;
        Sleep(800);
       // std::cout<<std::endl;

        confirm = true;
    }

    return addressInput;
}

int confirmSend::sendAmount()
{
    Sleep(100);     //delay so user doesn't accidentally input twice

    bool confirm = false;
    int amount;

    while(!confirm)
    {
       // std::cin.clear();
       // std::cin.ignore(1000,'\n');

        system("cls");
        std::cout << "type 0 to cancel..." << std::endl;
        std::cout<<std::endl;
        std::cout << "Enter how much to send:" << std::endl;
        std::cin >> amount;
        std::cout << std::endl;

        confirm = true;
    }

    return amount;
}

1 Ответ

0 голосов
/ 05 марта 2019

После ввода каждого std :: cin и нажатия кнопки «Ввод» в буфере cin останется '\ n', и вам потребуется какой-то метод для его устранения.Если есть только '\ n' или другие, используйте getchar() в качестве простого решения.И если перед '\ n' есть больше символов, вы можете использовать getline(), чтобы удалить их все, пока не получите '\ n'.

...