How to make the cin show in the same spot each time for c++ console

早过忘川 提交于 2019-12-11 07:42:07

问题


In the following code, I have the game board stay the same. I have the program looping so that the user can recycle the cards through as many times as they want. I would like it so that the character typed by the user will show in the exact same spot each time, instead of creating a new line. I would like for it to show so they can see what they typed before they hit enter. I am still pretty new to coding and I am in my 2nd C++ class, and I wish to learn and impress. To start off, I am using Microsoft Visual Studio 2013. Through research I got this code built:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <Windows.h>
#include <string>

using namespace std;

const TCHAR SUITS[] = { 'H', 'C', 'D', 'S' };
const TCHAR FACES[] = { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
const TCHAR SPACE = ' ';
const int number_of_cards = 5;

int main() {
    char * line_of_stars = "*****************************************************\n";
    char * line_of_spaces = "*                                                   *\n";
    char * top_of_cards = "*  *******   *******   *******   *******   *******  *\n";
    char * card_sides = "* *       * *       * *       * *       * *       * *\n";
    char quit = 'q';
    //Display Screen
    cout << line_of_spaces << top_of_cards << card_sides << card_sides << card_sides
         << card_sides << card_sides << top_of_cards << line_of_spaces << line_of_stars;
    cout << "\nPress 'q' to quit or any other key to get new cards: ";

    DWORD dw;
    COORD suitCoord;
    COORD faceCoord;
    COORD nextMove;
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hStdOut == INVALID_HANDLE_VALUE){ 
        printf("Invalid handle"); 
    }
    nextMove.X = 53;
    nextMove.Y = 11;
    do {
        for (int i = 0; i < number_of_cards; i++){

            int startX = 6 + (i * 10);
            int startY = 3;

            //Set coords for the i-nth card
            suitCoord.X = (startX);
            suitCoord.Y = (startY);
            faceCoord.X = (startX);
            faceCoord.Y = (startY + 2);
            //suit random num
            int rand1 = rand() % 4;
            TCHAR suit_char = SUITS[rand1];
            int rand2 = rand() % 13;
            TCHAR face_char = FACES[rand2];
            //Print to screen
            WriteConsoleOutputCharacter(hStdOut, &suit_char, 1, suitCoord, &dw);
            WriteConsoleOutputCharacter(hStdOut, &face_char, 1, faceCoord, &dw);
        }
        // Cover Last input with a space
        WriteConsoleOutputCharacter(hStdOut, &SPACE, 1, nextMove, &dw);
        cin.clear();
        cin >> quit;
        cout << "\b\b";
    } while (!(quit == 'q' || quit == 'Q'));

    return 0;
}

I have it so that the the program puts a space in the spot where the initial that the user will type the first input. After the first input the cin character shows on the next line until the user types 'q' or 'Q'. I would like for it to show in the same spot each time. The X coord should be: 51 and the Y coord should be: 12. I am trying not to use the clear screen technique because I used that for my final last semester and it flashed a lot reprinting the lines.


回答1:


One way to achieve this would be to move the cursor position each time they enter a number

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { 0, 0 });

This code should work:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <Windows.h>
#include <string>

using namespace std;

const TCHAR SUITS[] = { 'H', 'C', 'D', 'S' };
const TCHAR FACES[] = { 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K' };
const TCHAR SPACE = ' ';
const int number_of_cards = 5;

int main() {
    char * line_of_stars = "*****************************************************\n";
    char * line_of_spaces = "*                                                   *\n";
    char * top_of_cards = "*  *******   *******   *******   *******   *******  *\n";
    char * card_sides = "* *       * *       * *       * *       * *       * *\n";
    char quit = 'q';
    //Display Screen
    cout << line_of_spaces << top_of_cards << card_sides << card_sides << card_sides
        << card_sides << card_sides << top_of_cards << line_of_spaces << line_of_stars;
    cout << "\nPress 'q' to quit or any other key to get new cards: ";

    DWORD dw;
    COORD suitCoord;
    COORD faceCoord;
    COORD nextMove;
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hStdOut == INVALID_HANDLE_VALUE){
        printf("Invalid handle");
    }
    nextMove.X = 53;
    nextMove.Y = 11;
    do {
        for (int i = 0; i < number_of_cards; i++){

            int startX = 6 + (i * 10);
            int startY = 3;

            //Set coords for the i-nth card
            suitCoord.X = (startX);
            suitCoord.Y = (startY);
            faceCoord.X = (startX);
            faceCoord.Y = (startY + 2);
            //suit random num
            int rand1 = rand() % 4;
            TCHAR suit_char = SUITS[rand1];
            int rand2 = rand() % 13;
            TCHAR face_char = FACES[rand2];
            //Print to screen
            WriteConsoleOutputCharacter(hStdOut, &suit_char, 1, suitCoord, &dw);
            WriteConsoleOutputCharacter(hStdOut, &face_char, 1, faceCoord, &dw);
        }
        // Cover Last input with a space
        WriteConsoleOutputCharacter(hStdOut, &SPACE, 1, nextMove, &dw);
        cin.clear();
        cin >> quit;
        cout << "\b\b";
        SetConsoleCursorPosition(hStdOut, { 53, 11 });
    } while (!(quit == 'q' || quit == 'Q'));

    return 0;
}

Also, there is nothing wrong with clearing the screen as long as you don't use system("cls");

You can use a function like this, to fill the console buffer with spaces.

void clearScreen(){
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD count, cellCount;
    if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) return;

    cellCount = csbi.dwSize.X *csbi.dwSize.Y;

    if (!FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), (TCHAR) ' ', cellCount, { 0, 0 }, &count))return;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { 0, 0 });
}



回答2:


You can use system("CLS") to clear the screen and then print everything again. You will just have to store your information somehow so that it is really easy to print, then just clear the screen and reprint. I don't think there is a way to modify on screen characters in a console program.




回答3:


void setPos(int x, int y)
{
    COORD coord;
    coord.X = x; coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    return;
}

Use a method such as this to continually set the cursor to the same location by passing in the same coordinates every time. It may be beneficial to set the position and then write some spaces/newlines to the console to "erase" the previous input then set the cursor back again.



来源:https://stackoverflow.com/questions/27339936/how-to-make-the-cin-show-in-the-same-spot-each-time-for-c-console

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!