C++ 返回(\r)断开端口

C++ 返回(\r)断开端口,c++,windows,command-line,c++17,cout,C++,Windows,Command Line,C++17,Cout,std::cout在我的按键字符串中打印额外字符,可能是因为“\r”,例如,如果按下“向右箭头”,当我按下向上箭头时,它会打印“按下=向上箭头OWW”,然后,当我再次按下向右箭头时,它会再次正常打印“按下=向右箭头”,但如果我按下除“向右箭头”以外的任何箭头键它在末尾打印一些不需要的额外字符 源代码: game.cpp #include "engine.h" #include <iomanip> Engine eng; int main() { wh

std::cout在我的按键字符串中打印额外字符,可能是因为“\r”,例如,如果按下“向右箭头”,当我按下向上箭头时,它会打印“按下=向上箭头OWW”,然后,当我再次按下向右箭头时,它会再次正常打印“按下=向右箭头”,但如果我按下除“向右箭头”以外的任何箭头键它在末尾打印一些不需要的额外字符

源代码: game.cpp

#include "engine.h"
#include <iomanip>

Engine eng;

int main() {
    while (eng.isRunning) {
        eng.getInput();
        std::cout << std::setw(5);
        std::cout << "\r X = " << eng.playerX;
        std::cout << "| Y = " << eng.playerY;
        std::cout << "| KEY = " << eng.keyPressed;
        Sleep(100);
    }
    return 0;
}
#包括“engine.h”
#包括
发动机工程;
int main(){
同时(在运行中){
eng.getInput();
std::cout playerY++;
此->按键按下=“向上箭头”;
打破
}
else if(GetAsyncKeyState(VK_向下)){
//向下箭头键
这->游戏--;
此->按键按下=“向下箭头”;
打破
}
else if(GetAsyncKeyState(VK_END)){
出口(0);
}
睡眠(255);
}
}
};
#恩迪夫
解决此问题的最佳/最简单方法?
我搜索和测试了3天,但没有找到任何东西,请帮助我。

由于您正在覆盖以前的输出,当您打印较短的字符串时,以前输出的额外字符仍会显示出来。将
\r
替换为
\n
以查看实际输出的内容


您可以在键名后输出一些空格,以用空格覆盖这些额外字符并将其删除。

因为您正在覆盖以前的输出,所以当您打印较短的字符串时,以前输出的额外字符仍会显示出来。将
\r
替换为
\n
以查看实际输出的内容


您可以在键名后输出一些空格,以用空格覆盖这些额外字符并将其删除。

查看您提供的代码后,我确实看到了代码设计中的一些问题或顾虑:我将对其进行分解,并解释一些可以提高代码质量的内容。我将从main.cpp开始,然后转到Engine类

您最初拥有以下功能:


下一个问题从主函数中while循环的条件表达式开始。 您目前有:

这没关系,但这更像是您的
引擎类设计的问题。这里您提供了一个任何人都可以访问的
公共成员
。让我们看看你的类声明/定义;您目前有:


<>但是,我也在你的<代码>引擎< <代码>代码> GETInPUT()/代码>函数中看到了很少的关注点,所以让我们来看一下。 第一部分是while循环的
条件语句和类的成员。最初,默认情况下,您将该值设置为
true
,但在代码中的任何地方,我都没有看到该值被更新。我们不需要改变这个,但是修复很简单,现在我们有了一种通过公共接口调用来改变这个成员的方法。由于我已将您的
设置为默认的GettingInput
false
;现在,您可以在进入while循环之前在此函数中设置此参数。我看到的最后一个问题是,当在
main的
while循环中调用此函数时;此函数从不返回值,并且从不使用返回值



至于你在
cout
中的bug的实际问题,用户:已经为你回答了这个问题。我只是想在代码方面多帮你一点忙

查看您提供的代码后,我确实看到了代码设计中的一些问题或顾虑:我将对其进行分解,并解释一些可以提高代码质量的内容。我将从main.cpp开始,然后转到Engine类

您最初拥有以下功能:


下一个问题从主函数中while循环的条件表达式开始。 您目前有:

这没关系,但这更像是您的
引擎类设计的问题。这里您提供了一个任何人都可以访问的
公共成员
。让我们看看你的类声明/定义;您目前有:


<>但是,我也在你的<代码>引擎< <代码>代码> GETInPUT()/代码>函数中看到了很少的关注点,所以让我们来看一下。 第一部分是while循环的
条件语句和类的成员。最初,默认情况下,您将该值设置为
true
,但在代码中的任何地方,我都没有看到该值被更新。我们不需要改变这个,但是修复很简单,现在我们有了一种通过公共接口调用来改变这个成员的方法。由于我已将您的
设置为默认的GettingInput
false
;现在,您可以在进入while循环之前在此函数中设置此参数。我看到的最后一个问题是,当在
main的
while循环中调用此函数时;此函数从不返回值,并且从不使用返回值



至于你在
cout
中的bug的实际问题,用户:已经为你回答了这个问题。我只是想在代码方面多帮你一点忙

我知道堆栈溢出告诉人们不要在评论中说“谢谢”,但是,谢谢你,伙计,真的帮助了我,并将在将来的代码中帮助我。@Pero我知道,但我也这么做了,但不是直接的。我会这样说:“我真的很感谢你的反馈或积极的批评,因为这只会帮助我成为一名更高效的程序员、软件工程师。”@Pero他们还说我不应该像上面那样给出答案。我不介意尽我所能帮忙。它甚至帮助我提高自己的技能。对今后的应用也有很大的参考价值。反正我是自学成才的。当我第一次开始学习编程时,我的第一语言是C和C++的结合。这是在90年代末20年代初
#ifndef ENGINE_H
#define ENGINE_H

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

class Engine {
public:
    // Game
    bool isRunning = true;
    bool gettingInput = true;

    // Player
    int playerX = 1;
    int playerY = 1;
    char playerModel = 'P';

    // Test / Debug
    std::string keyPressed;

    // Functions
    char getInput() {
        // Gets arrow keys states
        while (this->gettingInput) {
            this->keyPressed = "";
            if (GetAsyncKeyState(VK_RIGHT)) {
                // Right arrow key
                this->playerX++;
                this->keyPressed = "Right arrow";
                break;
            }
            else if (GetAsyncKeyState(VK_LEFT)) {
                // Left arrow key
                this->playerX--;
                this->keyPressed = "Left arrow";
                break;
            }
            else if (GetAsyncKeyState(VK_UP)) {
                // Up arrow key
                this->playerY++;
                this->keyPressed = "Up arrow";
                break;
            }
            else if (GetAsyncKeyState(VK_DOWN)) {
                // Down arrow key
                this->playerY--;
                this->keyPressed = "Down arrow";
                break;
            }
            else if (GetAsyncKeyState(VK_END)) {
                exit(0);
            }
            Sleep(255);
        }
    }
};

#endif
#include "engine.h"
#include <iomanip>

Engine eng;

int main() {
    while (eng.isRunning) {
        eng.getInput();
        std::cout << std::setw(5);
        std::cout << "\r X = " << eng.playerX;
        std::cout << "| Y = " << eng.playerY;
        std::cout << "| KEY = " << eng.keyPressed;
        Sleep(100);
    }
    return 0;
}
#include "engine.h"
#include <iostream>
#include <iomanip>

int main() {
    Engine eng; // declare it here as the first object in main; now it has local
                // scope within main's function and is now in Automatic Storage 
                // instead of Global Storage.
    while( ... ) {
        // ....
    }
    return 0;
};
while( engine.isRunning ) { //... }
#ifndef ENGINE_H
#define ENGINE_H

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

class Engine {
public:
    // Game
    bool isRunning = true;
    bool gettingInput = true;

    // Player
    int playerX = 1;
    int playerY = 1;
    char playerModel = 'P';

    // Test / Debug
    std::string keyPressed;

    // Functions
    char getInput() { // ... }
};

#endif
#ifndef ENGINE_H
#define ENGINE_H

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

class Engine {
private:
    bool isRunning;
    bool gettingInput;

    // Player
    int playerX;
    int playerY;
    char playerModel;

    // Test / Debug
    std::string keyPressed;

 public:
    Engine() : 
      isRunning( false ),
      isGettingInput( false ),
      playerX( 1 ),
      playerY( 1 ),
      playerModel( 'P' ) 
    {}

    void run() { isRunning = true; // set or call other things here... }

    // Since we protected our members variables by making them private,
    // we now need some access functions to retrieve and modify them.
    bool isActive() const { return isRunning; } // make this const so it doesn't change anything
    void toggleIsActive() { isRunning = !isRunning; }

    bool retrievingInput() const { return isGettingInput; }
    void toggleRetrievingInput() { isGettingInput = !isGettingInput; } 

    int getPlayerX() const { return playerX; }
    void setPlayerX( int newX ) { playerX = newX; }

    int getPlayerY() const { return playerY; }
    void setPlayerY( int newY ) { playerY = newY; }

    // set both in one function call
    void setPlayerPosition( int newX, int newY ) {
        playerX = newX;
        playerY = newY;
    }

    char getPlayerModel() const { return playerModel; }
    // don't know if you want to change this: uncomment if you do
    // void setPlayerModel( char c ) { playerModel = c; }

    std::string& getPressedKey() const { return keyPressed; }

    char getInput() { // ... }
};    
int main () {
    Engine eng;
    eng.run(); // this now starts the engine sets the flag to true

    while (...) { //... }

    return 0;
}
char getInput() {
    // Gets arrow keys states
    while (this->gettingInput) {
        this->keyPressed = "";
        if (GetAsyncKeyState(VK_RIGHT)) {
            // Right arrow key
            this->playerX++;
            this->keyPressed = "Right arrow";
            break;
        }
        else if (GetAsyncKeyState(VK_LEFT)) {
            // Left arrow key
            this->playerX--;
            this->keyPressed = "Left arrow";
            break;
        }
        else if (GetAsyncKeyState(VK_UP)) {
            // Up arrow key
            this->playerY++;
            this->keyPressed = "Up arrow";
            break;
        }
        else if (GetAsyncKeyState(VK_DOWN)) {
            // Down arrow key
            this->playerY--;
            this->keyPressed = "Down arrow";
            break;
        }
        else if (GetAsyncKeyState(VK_END)) {
            exit(0);
        }
        Sleep(255);
    }
}