控制台输出重复? C ++

时间:2016-01-30 14:31:42

标签: c++ windows visual-studio

我正在开发一个C ++程序,它要求输入用户名和密码,然后将您登录到控制台(某种程度)。登录后,它会在我的代码中显示我的cout&ed;两次(MYCONSOLE:MYCONSOLE :)。我没有很好地解释,但希望我的代码会给你一个更好的主意。知道我的错误是什么吗? PS请不要恨我,如果解决方案很简单,我对这个语言来说真的很新。 =)

#include <iostream>
#include <conio.h>
#include <string>
#include <stdio.h>
#include <windows.h>

using namespace std;
int successfullogin();
/*USERNAME:ROOT
  PASSWORD:TOOR*/

//Login Screen
int main() {
    string username;
    string password;
    cout << "Enter UserName: ";
    cin >> username;
    cout << endl;
    if (username == "root") {
        cout << "Enter PassWord: ";
        cin >> password;
        if (password == "toor") {
            system("cls");
            cout << endl << "Login Successful... \n \nPlease wait while console is being initialised...";
            Sleep(5000);
            system("cls");
            successfullogin();
        }
        else {
            cout << endl << "Incorrect Password \a";
            system("color 4");
            _getch();
            system("cls");
            system("color f");
            main();
        }
    }
    else {
        cout << "Incorrect Username \a";
        system("color 4");
        _getch();
        system("cls");
        system("color f");
        main();
    }
}


//Console
int successfullogin()
{
    string input;
    input.clear();
    cout << "MYCONSOLE: ";
    getline(cin, input);
    if (input == "shutdown")
    {
        return 0;
    }
    else
    {
        cout << "MYCONSOLE: " << input << endl;
        _getch();
        system("cls");
        successfullogin();
    }
    return 0;
}

2 个答案:

答案 0 :(得分:0)

尝试添加这些行

  cin.clear();
  cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');

successfullogin

的开头

问题似乎是cin仍有一些事情可供您使用,所以getline会立即返回。

正如Joachim Pileborg和我自己的评论中提到的,你不应该进行递归调用。您的main可能会像:

int main() {
  while(1)    // Use an "endless" loop
  {
    string username;
    string password;
    cout << "Enter UserName: ";
    cin >> username;
    cout << endl;
    if (username == "root") {
        cout << "Enter PassWord: ";
        cin >> password;
        if (password == "toor") {
            system("cls");
            cout << endl << "Login Successful... \n \nPlease wait while console is being initialised...";
            Sleep(5000);
            system("cls");
            successfullogin();

            break; // To end the while(1) loop
        }
        else {
            cout << endl << "Incorrect Password \a";
            system("color 4");
            _getch();
            system("cls");
            system("color f");
            // main(); remove line
        }
    }
    else {
        cout << "Incorrect Username \a";
        system("color 4");
        _getch();
        system("cls");
        system("color f");
        // main(); remove line
    }
  }
}

这同样适用

int successfullogin()
{
  cin.clear();
  cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
  while(1)
  {
    string input;
    input.clear();
    cout << "MYCONSOLE: ";
    getline(cin, input);
    if (input == "shutdown")
    {
        return 0;
    }
    else
    {
        cout << "MYCONSOLE: " << input << endl;
        _getch();
        system("cls");
        // successfullogin(); remove line
    }
  }

  return 0;
}

答案 1 :(得分:0)

添加cin.ignore(INT_MAX,'\ n');在successfullogin方法中将完成这项工作。 像这样:

cin.ignore(INT_MAX, '\n');
getline(cin,input);

根据Cpp参考部分的注释:

http://en.cppreference.com/w/cpp/string/basic_string/getline

你正在混合cin&gt;&gt;来自cin的getline风格。 这样就可能发生新的行'\ n'没有从cin流中替换,并且会立即通过getline调用返回。

屏幕清晰解决方案的一个好方法:

void clear(){
    CONSOLE_SCREEN_BUFFER_INFO Info;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &Info);
    SHORT Width = Info.srWindow.Right - Info.srWindow.Left + 1;
    for (SHORT N = Info.srWindow.Top; N <= Info.srWindow.Bottom; ++N) {
        DWORD Chars;
        COORD Pos = { Info.srWindow.Left, N };
        FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ' ', Width, Pos, &Chars);
        FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0, Width, Pos, &Chars);
    }
    COORD TopLeft = { Info.srWindow.Left, Info.srWindow.Top };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), TopLeft);
}