我的代码点是打印到控制台,当提供 r,b,g或o 键盘时显示 RED,BLUE,GREEN或OFF 输入。 x 键盘输入终止。
还会输出一堆 SPACE 字符,并设置背景颜色,以便在终端中显示一个坚实的颜色块:
int i;
for (i=0;i<21;i++) { // for loop to print a load of empty lines
cout << " \n";
} // end of for loop
这一切都可以开始,但是在第十次更改后(即按 r,b,g或o 后跟 ENTER ),固体颜色块溢出 \ n 字符。
有人能说出为什么会这样吗?
我还预计 int main()中的else语句会处理与预期 r,b,g,o或x 。 它适用于单个字符,但是如果输入了多个字符,它将变得非常棘手,连续滚动而不是停止输入。
为什么会这样?
完整代码(通过NppExec编译MinGW g ++。exe,在Win7上运行cmd):
#include <windows.h>
#include "iostream"
using namespace std;
/*******FUNCTION PROTOTYPES*********/
void TermClr(int ClrHeight);
void SetColor(int value);
void PrintOut(int output, int col1, int col2);
/*******MAIN PROGRAM****************/
int main() {
int output = 0; // variable for current colour being output, 0-3 for OFF, RED, BLUE, GREEN
char inkey[2]; // console input written to the INKEY variable
PrintOut(0,119,7); // calls printout function, dark grey background for the light, normal grey for text
while(1){ //while loops forever until break
cin.getline(inkey,2); //waits for input, stored to INKEY
if(!strcmp(inkey,"x")){ // string compare whether INKEY matches "x"
cout << "\nProgram Terminated in\n3...";
Sleep(1000);
cout << "\n2...";
Sleep(1000);
cout << "\n1...";
Sleep(1000);
break; //breaks if 'x' is input
} // end if inkey x
else if(!strcmp(inkey,"o")){
PrintOut(0,119,7); // calls PrintOut function, 'output' set to 0, red background for the light, red for text
continue;
} // end of if inkey o
else if(!strcmp(inkey,"r")){
PrintOut(1,204,12);
continue;
} // end of if inkey r
else if(!strcmp(inkey,"b")){
PrintOut(2,153,9);
continue;
} // end of if inkey b
else if(!strcmp(inkey,"g")){
PrintOut(3,170,10);
continue;
} // end of if inkey g
else{
TermClr(30);
printf("Input not recognized\n(x=terminate, o=off, r=red, b=blue, g=green)");
continue;
} // end of else
} //end of while
return 0;
} // end of main
/*******FUNCTIONS*******************/
// function to clear terminal - ClrHeight is the number of new rows, use enough in the function call to clear the terminal
void TermClr(int ClrHeight) {
int i;
for ( i = 0; i < ClrHeight; i++ ) {
putchar('\n');
} // end of for loop
} // end TermClr
// function for changing terminal font colours (run the exe in cmd prompt to see colours, doesn't work in nppexec)
void SetColor(int value){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), value);
} // end SetColor
// function to print the required text to terminal
void PrintOut(int output, int col1, int col2) { // three inputs needed, the 'output' variable 0-3, the light colour text type, and the writing text type
TermClr(5); // calls func to clear teminal, 5 rows
const char *light[4] = {"OFF", "RED", "BLUE", "GREEN"}; // defines the four light colours
SetColor(col1);
int i;
for (i=0;i<21;i++) { // for loop to print a load of empty lines with the background colour 'col1'
cout << " \n";
} // end of for loop
SetColor(7);
cout << "\nColour - ";
SetColor(col2); // calls the function to change the console font colour (shows if run in cmd prompt, but not nppexec console)
cout << light[output];
SetColor(7);
cout << " (Output " << output << ")\n(x=terminate, o=off, r=red, b=blue, g=green)";
} //end PrintOut
已编辑添加:
image showing the issues
我已经尝试使用std :: endl代替\ n,它没有区别
进一步编辑:
如果我减少纯色的for循环中的迭代次数,即
int i;
for (i=0;i<3;i++) { // for loop to print a load of empty lines
cout << " \n";
} // end of for loop
所以通过while循环每次打印的行总数较少,在输出溢出之前我会得到更多的更改,但是经过足够的时间后仍然会发生。
编辑3:
评论中的Mark Ransom将cmd窗口确定为第一个问题的罪魁祸首。增加缓冲区高度允许在不良行为之前进行更多的程序循环。 (ALT + SPACE,属性,布局选项卡)
James Whyte的答案修复了多个键盘输入的问题,虽然我确实需要做一些工作,以便忽略错误输入而不是单独解释每个字符
编辑4:
如果我使用system("CLS")
而不是添加新行来清除屏幕,则缓冲区大小不再重要(猜测每次调用它时都会清除它)。我知道这是不好的做法,但是地狱,它的确有效!任何人都有另一种不是不好的做法吗?
答案 0 :(得分:1)
[编辑] ! - 至少这是两个字符问题永远循环的修复。
出现的问题是由于使用了char数组而不是单数字符,我相信。我把你的代码带入了一个新项目并且没有问题地重复了你的问题(有趣的笑话),并且决定做一个小修复工具来删除这个bug。
当您尝试将行放入已在其中包含未清除的值的char数组时,会出现问题。它只是决定跨过它,以一个永无止境的循环案例结束。
/*******MAIN PROGRAM****************/
int main() {
int output = 0; // variable for current colour being output, 0-3 for OFF, RED, BLUE, GREEN
char inkey; // console input written to the INKEY variable
PrintOut(0, 119, 7); // calls printout function, dark grey background for the light, normal grey for text
while (1) { //while loops forever until break
cin >> inkey; //waits for input, stored to INKEY
if (inkey == 'x') { // string compare whether INKEY matches "x"
cout << "\nProgram Terminated in\n3...";
Sleep(1000);
cout << "\n2...";
Sleep(1000);
cout << "\n1...";
Sleep(1000);
break; //breaks if 'x' is input
} // end if inkey x
else if (inkey == 'o') {
PrintOut(0, 119, 7); // calls PrintOut function, 'output' set to 0, red background for the light, red for text
continue;
} // end of if inkey o
else if (inkey == 'r') {
PrintOut(1, 204, 12);
continue;
} // end of if inkey r
else if (inkey == 'b') {
PrintOut(2, 153, 9);
continue;
} // end of if inkey b
else if (inkey == 'g') {
PrintOut(3, 170, 10);
continue;
} // end of if inkey g
else {
TermClr(30);
printf("Input not recognized\n(x=terminate, o=off, r=red, b=blue, g=green)");
continue;
} // end of else
} //end of while
return 0;
} // end of main
最后,如果您只需要在任何一点读取单个字符,请不要使用char数组和字符串比较。比较上面的各个字符,或者更好的是,使用以下行中的开关案例,以便更具可读性。
switch (inkey)
{
case 'r': PrintOut(1, 204, 12); continue; // Print red square.
case 'g': PrintOut(2, 153, 9); continue; // Print green square.
case 'b': PrintOut(3, 170, 10); continue; // Print blue square.
case 'o': PrintOut(0, 119, 7); continue; //Print a grey block for inactive.
case 'x':
cout << "\nProgram Terminated in\n3...";
Sleep(1000);
cout << "\n2...";
Sleep(1000);
cout << "\n1...";
Sleep(1000);
break; //breaks if 'x' is input
default:
TermClr(30);
printf("Input not recognized\n(x=terminate, o=off, r=red, b=blue, g=green)");
continue;
} // end switch
答案 1 :(得分:0)
下面发布的最终工作代码。
根据Mark Ransom在原始问题下的评论,第一个问题被确定为cmd缓冲区高度。
我使用system("CLS");
解决了这个问题,以清除屏幕。 (我知道这被认为是不好的做法,但我写过的任何代码都只供个人使用,而且这是我能让它工作的唯一方法。)
当输入多个字符时的滚动问题被James Whyte在他的回答中正确识别和纠正,然而,它揭示了另一个问题(在我看来是一个真正的耻辱,因为我发现切换/案例语法为更加优雅!) -
如果输入了多个字符,则会依次解释每个字符并运行while循环。因此,如果我输入&#34; rgb&#34;,显示屏将闪烁通过&#34; r&#34;和&#34; g&#34;在确定&#34; b&#34;之前的输出输出。通过回到原始字符数组&amp;字符串比较解决方案,并添加if(inkey.length() == 1)
循环,可以捕获除单个字符以外的任何内容,并且用户通知输入无效。
最后,我希望在收到无效输入时,先前显示的输出将保留。这是通过为前一个输出添加变量,并为PrintOut
函数
代码:
#include <windows.h>
#include "iostream"
using namespace std;
int outputprev;
int col1prev;
int col2prev;
/*******FUNCTION PROTOTYPES*********/
void SetColor(int value);
void PrintOut(int output, int col1, int col2);
/*******MAIN PROGRAM****************/
int main() {
int output = 0; // variable for current colour being output, 0-3 for OFF, RED, BLUE, GREEN
string inkey; // console input written to the INKEY variable
PrintOut(0, 119, 7); // calls printout function, dark grey background for the light, normal grey for text
while(inkey != "x"){ //while loops forever until break
getline(cin, inkey); //waits for input, stored to INKEY
if(inkey.length() == 1) {
if(inkey.compare("o") == 0){
PrintOut(0,119,7); // calls PrintOut function, 'output' set to 0, red background for the light, red for text
continue;
} // end of if inkey o
else if(inkey.compare("r") == 0){
PrintOut(1,204,12);
continue;
} // end of if inkey r
else if(inkey.compare("b") == 0){
PrintOut(2,153,9);
continue;
} // end of if inkey b
else if(inkey.compare("g") == 0){
PrintOut(3,170,10);
continue;
} // end of if inkey g
else{
PrintOut(outputprev, col1prev, col2prev); // Print for previous value
cout << " **INVALID INPUT**";
continue; } // end of else
} // end of if input length
else {
PrintOut(outputprev, col1prev, col2prev); // Print for previous value
cout << " **INVALID INPUT**";
continue; // end of else
}
} //end of while
cout << "\nProgram Terminating";
Sleep(1000);
return 0;
} // end of main
/*******FUNCTIONS*******************/
// function for changing terminal font colours (run the exe in cmd prompt to see colours, doesn't work in nppexec)
void SetColor(int value){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), value);
} // end SetColor
// function to print the required text to terminal
void PrintOut(int output, int col1, int col2) { // three inputs needed, the 'output' variable 0-3, the light colour text type, and the writing text type
outputprev = output;
col1prev = col1;
col2prev = col2;
system("CLS");
const char *light[4] = {"OFF", "RED", "BLUE", "GREEN"}; // defines the four light colours
SetColor(col1);
putchar('\n');
int i;
for (i=0;i<20;i++) { // for loop to print a load of empty lines with the background colour 'col1'
cout << " \n";
} // end of for loop
SetColor(7);
cout << "\nColour - ";
SetColor(col2); // calls the function to change the console font colour (shows if run in cmd prompt, but not nppexec console)
cout << light[output];
SetColor(7);
cout << " (Output " << output << ")\n(x=terminate, o=off, r=red, b=blue, g=green)";
} //end PrintOut