현재 인쇄된 콘솔 라인 지우기
C에서 현재 인쇄된 콘솔 행을 지우려면 어떻게 해야 합니까?Linux 시스템에서 작업하고 있습니다.예:
printf("hello");
printf("bye");
안녕하세요 대신 같은 줄에 bye를 출력하고 싶습니다.
가치 있는 미묘함...
\33[2K
가 현재 행 .
\033[A
커서를 한 줄 위로 이동하지만 같은 열(즉, 줄의 시작 부분)로 이동하지 않습니다.
\r
커서를 줄의 선두로 가져옵니다(r은 캐리지 리턴 N.B. 캐리지 리턴은 새 줄을 포함하지 않으므로 커서가 같은 줄에 유지됨). 그러나 아무것도 지워지지 않습니다.
만, 부터 다시 및 @입니다.\33[2K\r
에서는, 새로운 행에, 카운트다운 .'\n'
fprintf()
어쩔 수 fflush()
않고 했습니다. 포인터 stdout에 했을 입니다.Linux에 쓰려고 했을 입니다.퍼 file FILE 。fdfile
이, 이 주소는 "Disclocking File Descriptor는 "Discriptor", "Discriptor", "Discriptor는 "Discriptor", "Discriptor는 "Discriptor" 입니다./dev/pts/21
fprintf(fdfile, "\33[2K\rT minus %d seconds...", i);
fflush(fdfile);
에는 \[ ]를모두 했습니다.\33 [ 2K ]는 과 같습니다.\r
캐리지 리턴 시퀀스를 사용하여 줄의 시작 부분에서 커서 위치를 변경합니다. 수 없었다fflush()
다음에fprintf()
에는 행 '\n'
가 필요 없는 가 필요합니다.ffflush() 행
fprintf(fdfile, "\033[A\33[2K\rT minus %d seconds...\n", i);
기입하는 행의 바로 위에 있는 행에 뭔가가 있는 경우, 그 행은 첫 번째 fprintf()로 덮어씁니다.첫 번째 이동을 한 줄 위로 이동하려면 위에 추가 행을 남겨야 합니다.
i = 3;
fprintf(fdfile, "\nText to keep\n");
fprintf(fdfile, "Text to erase****************************\n");
while(i > 0) { // 3 second countdown
fprintf(fdfile, "\033[A\33[2KT\rT minus %d seconds...\n", i);
i--;
sleep(1);
}
VT100 이스케이프 코드를 사용할 수 있습니다.xterm을 포함한 대부분의 단말기는 VT100을 지원합니다.선을 지우는 경우, 이것은^[[2K
C에서 이것은 다음을 나타낸다.
printf("\33[2K\r");
'어울리다'를 사용할 수 요.\r
(반환) 커서를 줄의 선두로 되돌리려면:
printf("hello");
printf("\rbye");
같은 행에 bye가 인쇄됩니다.기존 캐릭터가 지워지는 것도 아니고, 안녕이 hello보다 짧기 때문에 byelo로 끝납니다.새 인쇄를 길게 하여 추가 문자를 덮어쓸 수 있습니다.
printf("hello");
printf("\rbye ");
또는 먼저 공백 몇 개로 지운 다음 새 문자열을 인쇄합니다.
printf("hello");
printf("\r ");
printf("\rbye");
그러면 hello가 인쇄되고 행의 선두로 이동하여 공백으로 덮어쓴 후 다시 선두로 돌아가서 bye가 인쇄됩니다.
이 스크립트는 예시에 맞게 하드 코딩되어 있습니다.
#include <stdio.h>
int main ()
{
//write some input
fputs("hello\n",stdout);
//wait one second to change line above
sleep(1);
//remove line
fputs("\033[A\033[2K",stdout);
rewind(stdout);
//write new line
fputs("bye\n",stdout);
return 0;
}
소스를 보려면 여기를 클릭하십시오.
\b 를 사용하여 행을 삭제할 수 있습니다.
printf("hello");
int i;
for (i=0; i<80; i++)
{
printf("\b");
}
printf("bye");
간단한 요령이 있지만 인쇄하기 전에 준비해야 합니다. 인쇄하고 싶은 것을 변수에 넣고 인쇄하면 끈을 제거할 길이를 알 수 있습니다.여기 예가 있습니다.
#include <iostream>
#include <string> //actually this thing is not nessasory in tdm-gcc
using namespace std;
int main(){
//create string variable
string str="Starting count";
//loop for printing numbers
for(int i =0;i<=50000;i++){
//get previous string length and clear it from screen with backspace charactor
cout << string(str.length(),'\b');
//create string line
str="Starting count " +to_string(i);
//print the new line in same spot
cout <<str ;
}
}
보통 문자열 끝에 '\r'이 있으면 줄 바꿈 없이 캐리지 리턴만 인쇄됩니다.다음이 있는 경우:
printf("fooooo\r");
printf("bar");
출력은 다음과 같습니다.
barooo
한 가지 제안할 수 있는 것은 (아마도 회피책으로 사용할 수 있는) NULL 끝의 고정 크기 문자열을 공백 문자로 초기화하여 (인쇄 전에 매번) strcpy를 사용하여 문자열을 복사하는 것입니다.그러면 이후의 모든 인쇄가 이전 문자열을 덮어쓰게 됩니다.다음과 같은 경우:
char str[MAX_LENGTH];
// init str to all spaces, NULL terminated with character as '\r'
strcpy(str, my_string); // copy my_string into str
str[strlen(my_string)] = ' '; // erase null termination char
str[MAX_LENGTH - 1] = '\r';
printf(str);
하면, 에러 체크를 실시할 수 .my_string
、 개 1 、 개 1 개 is is is is is is is is is is보다 가 항상 .str
본적적 ?? ?? ????
다른 사람들은 이미 OP의 질문에 대답했습니다.다음은 캐리지 리턴이 Linux 머신에서와 같은 동작을 하는 이유에 대해 궁금해하는 분들을 위한 답변입니다.
캐리지 리턴 문자의 동작은 플랫폼에 의존합니다.
C11 표준의 섹션 '5.2.2 문자 표시 의미론'에서:
\r(캐리지 리턴) 활성 위치를 현재 라인의 초기 위치로 이동합니다.
POSIX 표준 섹션 '3.86 캐리지 리턴 문자(< 캐리지 리턴 문자)'(https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html):
출력 스트림에서 캐리지 리턴이 발생한 것과 같은 실제 행의 선두에서 인쇄를 시작해야 함을 나타내는 문자.C언어에서 '\r'로 지정된 문자입니다.이 문자가 회선의 선두로 이동하기 위해 시스템에 의해 출력 장치로 전송되는 정확한 시퀀스인지 여부는 지정되지 않았습니다.
캐리지 리턴이 행 전체를 소거(=> NUL 문자로 채워야 하는지) 여부는 기재되어 있지 않습니다.내 추측으로는 지우면 안 될 것 같아.
그러나 Linux 머신(x86_64와 ARM32에서 모두 시도)에서는 캐리지 리턴 문자가 커서를 현재 행의 선두로 이동하고 행에 "\0" 문자(NUL 문자)를 채우는 것을 볼 수 있었습니다.이러한 NUL 문자를 인식하려면 , glibc printf 를 개입시켜 콜 하는 대신에, 코드에서 직접 기입 시스템 콜을 콜 할 필요가 있습니다.
다음 코드 스니펫을 예로 들어 보겠습니다.
printf("hello");
printf("\rbye");
beaglebone black(32비트 ARM) bash 터미널에서 이 기능을 구축 및 실행합니다.
ubuntu@arm:~$ ./a.out
byeubuntu@arm:~$
write syscall에서의 strace 출력:
bye) = 9 9hello
+++ exited with 4 +++
i
문자 배열 단어를 반복한다. j
단어 길이를 추적합니다. "\b \b"
는 회선을 넘으면 워드를 지웁니다.
#include<stdio.h>
int main()
{
int i = 0, j = 0;
char words[] = "Hello Bye";
while(words[i]!='\0')
{
if(words[i] != ' ') {
printf("%c", words[i]);
fflush(stdout);
}
else {
//system("ping -n 1 127.0.0.1>NUL"); //For Microsoft OS
system("sleep 0.25");
while(j-->0) {
printf("\b \b");
}
}
i++;
j++;
}
printf("\n");
return 0;
}
이 오래된 실마리를 찾았는데, 실제 줄을 비워둘 탈출 시퀀스를 찾고 있어.
printf가 쓴 글자 수를 돌려준다는 생각을 아무도 하지 못했다(혹은 내가 놓쳤다)는 것이 꽤 재미있습니다.따라서 '\r' + 빈 글자 수만큼 printf가 반환되는 대로만 인쇄하면 미리 작성된 텍스트가 완전히 비워집니다.
int BlankBytes(int Bytes)
{
char strBlankStr[16];
sprintf(strBlankStr, "\r%%%is\r", Bytes);
printf(strBlankStr,"");
return 0;
}
int main(void)
{
int iBytesWritten;
double lfSomeDouble = 150.0;
iBytesWritten = printf("test text %lf", lfSomeDouble);
BlankBytes(iBytesWritten);
return 0;
}
VT100을 사용할 수 없기 때문에 그 솔루션을 계속 사용해야 할 것 같습니다.
echo -e "hello\c" ;sleep 1 ; echo -e "\rbye "
위의 명령어는 어떻게 동작합니까?
hello가 인쇄되고 커서가 "o" 위치에 유지됩니다(\c 사용).
그러면 1초 동안 기다립니다(sleep 1).
그럼 안녕으로 대체되겠네요.(\r 사용)
NOTE : Using ";", We can run multiple command in a single go.
Windows 10에서는 현재 콘솔에서 VT100 모드를 활성화하여 다음과 같이 이스케이프 시퀀스를 사용함으로써 VT100 스타일을 사용할 수 있습니다.
#include <windows.h>
#include <iostream>
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#define DISABLE_NEWLINE_AUTO_RETURN 0x0008
int main(){
// enabling VT100 style in current console
DWORD l_mode;
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleMode(hStdout,&l_mode)
SetConsoleMode( hStdout, l_mode |
ENABLE_VIRTUAL_TERMINAL_PROCESSING |
DISABLE_NEWLINE_AUTO_RETURN );
// create a waiting loop with changing text every seconds
while(true) {
// erase current line and go to line begining
std::cout << "\x1B[2K\r";
std::cout << "wait a second .";
Sleep(1);
std::cout << "\x1B[2K\r";
std::cout << "wait a second ..";
Sleep(1);
std::cout << "\x1B[2K\r";
std::cout << "wait a second ...";
Sleep(1);
std::cout << "\x1B[2K\r";
std::cout << "wait a second ....";
}
}
다음 링크 참조: Windows VT100
언급URL : https://stackoverflow.com/questions/1508490/erase-the-current-printed-console-line
'itsource' 카테고리의 다른 글
하위 구성 요소에 Vue Prop가 정의되지 않았습니다. (0) | 2022.08.27 |
---|---|
Vue.js 어레이에서 항목을 삭제하는 방법 (0) | 2022.08.27 |
const char * 를 사용하는 경우 및 const char [] 를 사용하는 경우 (0) | 2022.08.27 |
양식 입력 변경 감지 방법 보기 (0) | 2022.08.27 |
버퍼 오버플로를 활성화하기 위해 gcc 컴파일러 최적화를 해제하는 방법 (0) | 2022.08.27 |