我正在使用带有特殊字符的c ++字符串来控制输出。大多数结果都可以预测,但其中一个结果超出了我的预期。我无法在任何地方找到答案。
平台:Windows 7企业版6.1(Build 7601:Service Pack 1)编译器:g ++(GCC)8.2.0,c ++ 17
#include <iostream>
int main(){
using namespace std;
char numString[12] = "0123456789\n";
//This is group 1
numString[3] = '\t';
numString[4] = '\b';
cout << "Group 1 output:\n" << numString << endl;
//This is group 2
numString[3] = '\b';
numString[4] = '\t';
cout << "Group 2 output:\n" << numString << endl;
//This is group 3
numString[3] = '\n';
numString[4] = '\b';
cout << "Group 3 output:\n" << numString << endl;
//This is group 4
numString[3] = '\b';
numString[4] = '\n';
cout << "Group 4 output:\n" << numString << endl;
//This is group 5
numString[2] = '\b';
numString[3] = '\b';
numString[4] = '\n';
cout << "Group 5 output:\n" << numString << endl;
return 0;
}
控制台中的输出:
第1组输出:
01256789
第2组输出:
01 56789
第3组输出:
012
56789
第4组输出:
012
56789
第5组输出:
01
56789
第四组产量预计为,
第4组输出:
01
56789
虽然输出实际上是,
第4组输出:
012
56789
我无法理解的是为什么角色'2'仍在那里。
有人可以帮我理解这个问题吗?谢谢。
在看到下面的答案,尤其是zar之后,我相信我已经理解了这个问题,并想在此总结一下。
Please pay attention to move the cursor.
I'd like to paste all of the code here:
//strwithspecialchar.cpp -- Understand special characters in C++ string
#include <iostream>
int main(){
using namespace std;
char numString[12] = "0123456789\n";
//This is group 1
numString[3] = '\t';
numString[4] = '\b';
cout << "Group 1 output:\n" << numString << endl;
//This is group 2
numString[3] = '\b';
numString[4] = '\t';
cout << "Group 2 output:\n" << numString << endl;
//This is group 3
numString[3] = '\n';
numString[4] = '\b';
cout << "Group 3 output:\n" << numString << endl;
//This is group 4
numString[3] = '\b';
numString[4] = '\n';
cout << "Group 4 output:\n" << numString << endl;
//This is group 5
numString[2] = '\b';
numString[3] = '\b';
numString[4] = '\n';
cout << "Group 5 output:\n" << numString << endl;
//This is group 6
numString[2] = '\b';
numString[3] = '3';
numString[4] = '\n';
cout << "Group 6 output:\n" << numString << endl;
//This is group 7
numString[2] = '2';
numString[3] = '\b';
numString[4] = '\a';
cout << "Group 7 output:\n" << numString << endl;
//This is group 8
numString[3] = '\b';
numString[4] = '\r';
cout << "Group 8 output:\n" << numString << endl;
//This is group 9
numString[3] = '\b';
numString[4] = '\n';
numString[8] = '\r';
cout << "Group 9 output:\n" << numString << endl;
return 0;
}
And the output below for better understanding these special characters:
Group 1 output:
01256789
Group 2 output:
01 56789
Group 3 output:
012
56789
Group 4 output:
012
56789
Group 5 output:
01
56789
Group 6 output:
03
56789
Group 7 output:
0156789
Group 8 output:
56789
Group 9 output:
012
967
发布于 2019-06-14 13:14:10
控制台显示的是正确的输出,即
Group 4 output:
012
56789
你错了预料到
Group 4 output:
01
56789
什么\b
性格确实是移动光标一个字符后面,它并没有将其删除。所以发生的事情是光标移回2但角色仍然存在。
012
^
下一个字符\n
不是可打印字符而是控制字符,它只是将光标移动到下一行,因此它不会覆盖已打印的字符。
如果你这样做:
//This is group 4
numString[3] = '\b';
numString[4] = 'X';
cout << "Group 4 output:\n" << numString << endl;
现在\b
移动到2但是下一个字符'X'立即覆盖它,产生如预期的以下结果。
Group 4 output:
01X56789
即使您添加另一个退格,另一个演示是:
numString[3] = '\b';
numString[4] = '\b';
numString[5] = '\n';
光标现在为1
012
^
Now it encounters the \n
(new line) as next character and it simply moves the cursor to the next line so 1 and 2 are never overwritten as they were already printed and remains now in the previous line.
The output hence now is, as expected:
Group 4 output:
012
6789
发布于 2019-06-14 13:53:35
这归结为您的终端。我们可以从一个平台上轻松看到,该平台不会'\b'
以任何特殊方式呈现控制字符,使其出现在预期位置的字符串中:
那么,为什么不“擦掉” 2
?
如果我们打开的cmd.exe和类型A,B,Ctrl+ H那么我们看到的B
将立即删除。这似乎反驳了cmd.exe 像许多控制台一样 “非破坏性地”处理退格的概念。
但它并没有反驳它!这似乎是对击键的特殊处理,可能与实际退格字符的工作方式有关。毕竟,您希望退格字符实际上擦除内容,而不仅仅是移动光标。
当在非键盘生成的输出中找到时,cmd.exe以不同方式处理控制字符:以非破坏性方式。因此它将光标向后移动,然后下一个字符“覆盖”将要删除的字符。
但是在第4组中,你有一个换行符,所以下一个字符出现在下一行,并且不在正确的位置删除任何内容。
我们可以在没有C ++的情况下重现这一点,方法是构造一个特殊文件,然后指示cmd.exe打印它:
“工作”
“不工作”
(您可以使用“编辑”/“字符面板”菜单项在Notepad ++中插入特殊字符ASCII 08。)
我的结论是不依赖控制代码来实现这样的“技巧”:如果你想从字符串中删除一个字符,实际上是这样做的; 如果你想创建一个GUI,要么实际上是这样做,要么用一个像ncurses这样聪明的库来模拟它。
https://stackoverflow.com/questions/-100009098
复制相似问题