Неожиданный результат "f \ t \ b \ bg \ n" под Visual C ++ - PullRequest
2 голосов
/ 04 марта 2012

Я написал однострочную программу на Visual C ++ 6.0 под Windows XP, но результаты привели меня в замешательство. Кто-нибудь может это объяснить?

#include "stdafx.h"

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

Вывод, который я получил:

fНажмите любую клавишу, чтобы продолжить.

Ответы [ 2 ]

4 голосов
/ 04 марта 2012

Итак, я немного поиграл с разными строками, и, насколько я могу судить, консоль Windows следует следующим правилам:

  • После обычного символа, \b перемещает курсор на одну позицию влево. (Это именно то, что вы ожидаете.)
  • После того, как \t переместил курсор n позиций вправо, a \b переместит курсор n позиции влево. (Я не уверен, что это то, чего я ожидал, но это имеет смысл.)
  • После того, как \b переместил курсор * на 1016 * n позиций влево, секунда \b переместит курсор на n позиций влево. (Это явно не предполагаемое поведение. Я не решаюсь использовать термин «ошибка», потому что я не знаю, было ли у них когда-либо намерение поддержать случай двух последовательных \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. Во-вторых, вы наблюдали Press any key to continue. сразу после * f (то есть, как в Visual Studio можно сказать, что консольное приложение закончилось), тогда как я заметил, что если я добавлю что-нибудь еще в конец строка, например, если моя строка была f\t\b\bg\nh\n, то это что-то большее переписало f. (Точно так же, если я прикрепил ; echo h к концу команды Bash.) То есть, в то время как в моем тестировании \n переместил курсор в начало исходной строки, в вашем тестировании Visual Studio каким-то образом знал, что напечатайте 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 странным образом заканчивается в середине A и BB.
1 голос
/ 04 марта 2012

Это было бы возможно, если бы вы написали g\n в прошлом до начала строки (т. Е. Индекс -1?), Поэтому я предполагаю, что вы пропускаете табуляцию и f и пишете g и перевод строки в никудаВозможно, в этом случае вкладка вставляет 0 пробелов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...