首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法理解带有特殊字符的C ++字符串的输出

无法理解带有特殊字符的C ++字符串的输出
EN

Stack Overflow用户
提问于 2019-06-14 04:37:14
回答 2查看 0关注 0票数 0

我正在使用带有特殊字符的c ++字符串来控制输出。大多数结果都可以预测,但其中一个结果超出了我的预期。我无法在任何地方找到答案。

平台:Windows 7企业版6.1(Build 7601:Service Pack 1)编译器:g ++(GCC)8.2.0,c ++ 17

代码语言:javascript
复制
#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;
}

控制台中的输出:

代码语言:javascript
复制
第1组输出:
01256789

第2组输出:
01      56789

第3组输出:
012
56789

第4组输出:
012
56789

第5组输出:
01
56789

第四组产量预计为,

代码语言:javascript
复制
第4组输出:
01
56789

虽然输出实际上是,

代码语言:javascript
复制
第4组输出:
012
56789

我无法理解的是为什么角色'2'仍在那里。

有人可以帮我理解这个问题吗?谢谢。

在看到下面的答案,尤其是zar之后,我相信我已经理解了这个问题,并想在此总结一下。

  1. Windows cmd console is in non-destructive mode when no physical keystrokes detected.
  2. Any new output starts overwriting the existing ones from the current cursor. Sounds redundant but necessary. If there is any new character output, it will overwrite the existing one until new characters are used up. If there are still more existing characters left, they will continue existing over there and may look like "output" behind the new characters.
  3. '\b' only moves the cursor one character back. It does not delete anything.
  4. '\n' only moves the cursor to the next line. It does not move any character behind it to the next line.
  5. '\r' only moves the cursor to the beginning of the current line.

Please pay attention to move the cursor.

I'd like to paste all of the code here:

代码语言:javascript
复制
//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:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2019-06-14 13:14:10

控制台显示的是正确的输出,即

代码语言:javascript
复制
Group 4 output:
012
56789

你错了预料到

代码语言:javascript
复制
Group 4 output:
01
56789

什么\b性格确实是移动光标一个字符后面,它并没有将其删除。所以发生的事情是光标移回2但角色仍然存在。

代码语言:javascript
复制
012
  ^

下一个字符\n不是可打印字符而是控制字符,它只是将光标移动到下一行,因此它不会覆盖已打印的字符。

如果你这样做:

代码语言:javascript
复制
//This is group 4
numString[3] = '\b';
numString[4] = 'X';
cout << "Group 4 output:\n" << numString << endl;

现在\b移动到2但是下一个字符'X'立即覆盖它,产生如预期的以下结果。

代码语言:javascript
复制
Group 4 output:
01X56789

即使您添加另一个退格,另一个演示是:

代码语言:javascript
复制
numString[3] = '\b';
numString[4] = '\b';
numString[5] = '\n';

光标现在为1

代码语言:javascript
复制
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:

代码语言:javascript
复制
Group 4 output:
012
6789

See also this and that

票数 0
EN

Stack Overflow用户

发布于 2019-06-14 13:53:35

这归结为您的终端。我们可以从一个平台上轻松看到,该平台不会'\b'以任何特殊方式呈现控制字符,使其出现在预期位置的字符串中

通过Coliru的一些“原始”输出的屏幕截图
通过Coliru的一些“原始”输出的屏幕截图

那么,为什么不“擦掉” 2

如果我们打开的cmd.exe和类型A,B,Ctrl+ H那么我们看到的B将立即删除。这似乎反驳了cmd.exe 像许多控制台一样 “非破坏性地”处理退格的概念。

但它并没有反驳它!这似乎是对击键的特殊处理,可能与实际退格字符的工作方式有关。毕竟,您希望退格字符实际上擦除内容,而不仅仅是移动光标。

当在非键盘生成的输出中找到时,cmd.exe以不同方式处理控制字符:以非破坏性方式。因此它将光标向后移动,然后下一个字符“覆盖”将要删除的字符。

但是在第4组中,你有一个换行符,所以下一个字符出现在下一行,并且不在正确的位置删除任何内容。

我们可以在没有C ++的情况下重现这一点,方法是构造一个特殊文件,然后指示cmd.exe打印它:

“工作”

非再现文件内容的屏幕截图
非再现文件内容的屏幕截图

非再现问题的屏幕截图
非再现问题的屏幕截图

“不工作”

再现文件内容的屏幕截图
再现文件内容的屏幕截图

再现问题的截图
再现问题的截图

(您可以使用“编辑”/“字符面板”菜单项在Notepad ++中插入特殊字符ASCII 08。)

我的结论是不依赖控制代码来实现这样的“技巧”:如果你想从字符串中删除一个字符,实际上是这样做的; 如果你想创建一个GUI,要么实际上是这样做,要么用一个像ncurses这样聪明的库来模拟它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100009098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档