Visual C ++下“f \ t \ b \ bg \ n”的意外结果

时间:2012-03-04 15:17:39

标签: c visual-c++ printf

我在Windows XP下用Visual C ++ 6.0编写了一个单行程序,但输出让我感到困惑。有人可以解释一下吗?

#include "stdafx.h"

int main(int argc, char* argv[])
{
    printf("f\t\b\bg\n");
    return 0;
}

我得到的输出是:

  

按任意键继续。

2 个答案:

答案 0 :(得分:4)

所以,我用不同的字符串玩了一下,据我所知,Windows控制台遵循以下规则:

  • 在常规字符后,\b将光标向左移动一个位置。 (这正如您所期望的那样。)
  • 将光标 n 位置向右移动\t后,\b将光标 n 移动到左侧。 (我不确定这是我所期望的,但它是有道理的。)
  • 将光标 n 位置向左移动\b后,第二个\b将光标 n 位置向左移动。 (这显然不是预期的行为。我对使用“bug”一词犹豫不决,因为我不知道他们是否有任何意图支持连续两个\b的情况,但显然不是“特征”。)
  • 我不完全理解与换行符的交互。我只想说在某些情况下\b能够移动到前一行,而在大多数情况下它不是;并且同一\n语句中较早的printf可以极大地影响\b\t的互动,即使是“远距离”(可以这么说)。

因此,在您的示例f\t\b\bg\n中,f打印f并将光标向右移动一个位置; \t打印七个空格并将光标向右移动七个位置(到下一个制表位);第一个\b不打印任何内容并将光标向左移动七个位置(撤消\t);第二个\b不打印任何内容并将光标向左移动另外七个位置(放置它,我不是你,在前一行上 ); g打印g(在前一行)并可能将光标向右移动一个位置;然后\n将光标向下移动到原始行。

现在,您观察到的和我观察到的内容之间存在两个小的差异。一个是我在前一行的末尾观察到g(看到它,向右滚动):

$ gcc -Wall -Wextra tmp.c -o tmp.exe && ./tmp.exe
tmp.c: In function 'main':
tmp.c:3:14: warning: unused parameter 'argc' [-Wunused-parameter]
tmp.c:3:26: warning: unused parameter 'argv' [-Wunused-parameter]                                                g
f

你显然没有;这个,我认为我从控制台运行它,而你通过Visual Studio运行它,所以你根本没有 上一行要打印g上。另一个是你在<{em> Press any key to continue.之后立即观察到f (这是Visual Studio说控制台应用程序已经结束的方式),而我观察到如果我添加了任何内容更多到字符串的结尾,例如,如果我的字符串是f\t\b\bg\nh\n,那么那些东西 - 更多覆盖 f。 (同样,如果我在; echo h添加到Bash命令的末尾。)也就是说,在我的测试中,\n将光标移动到原始行的开头,在测试Visual中工作室以某种方式知道在行后的Press any key to continue.之后打印f 。但我不是太挂了;我真的不知道Visual Studio如何决定打印Press any key to continue.的位置,并且它很可能使用比光标位置更复杂(或更“复杂”)的东西。


为了完整起见,以下是一些字符串示例,在我看来,它们证明了上述结论:

printf                  console output
----------------------------------------------
"A\bB\n"                B
"A\b\bB\n"              B            [see note 1]
"AB\bC\n"               AC
"AB\b\bC\n"             CB
"AB\b\b\bC\n"           CB           [see note 1]
"A\t\bB\n"              AB
"A\t\t\b\bB\n"          B            [see note 2]
"A\tBB\t\b\bC\n"        A   C   BB   [see note 3]

注意:

  1. 在这些情况下,多余的\b移动到上一行。
  2. 第一个\t移动七个空格;第二个\t移动八个;每个\b移动八个。因此B最终会覆盖A
  3. 第二个\t仅移动六个空格,因此每个\b移动六个,C奇怪地在ABB的中间结束

答案 1 :(得分:1)

如果你在行开始之前写了g\n(即索引-1?),这是可能的,所以我猜你是跳过制表符f并写g和新线无处可去。也许tab在这种情况下插入0个空格。