현재 인쇄 된 콘솔 줄 지우기
C에서 현재 인쇄 된 콘솔 줄을 어떻게 지울 수 있습니까? Linux 시스템에서 작업 중입니다. 예를 들면-
printf("hello");
printf("bye");
hello 대신 같은 줄에 bye를 인쇄하고 싶습니다.
VT100 이스케이프 코드를 사용할 수 있습니다 . xterm을 포함한 대부분의 터미널은 VT100을 인식합니다. 줄을 지우려면 이것은입니다 ^[[2K
. C에서는 다음을 제공합니다.
printf("%c[2K", 27);
\r
( 캐리지 리턴 )을 사용하여 커서를 줄의 시작 부분으로 되돌릴 수 있습니다 .
printf("hello");
printf("\rbye");
이것은 같은 줄에 작별 인사 를 인쇄 합니다. 그래도 기존 문자는 지워지지 않으며 bye 가 hello 보다 짧기 때문에 byelo로 끝납니다 . 지우려면 새 인쇄물을 더 길게 만들어 추가 문자를 덮어 쓸 수 있습니다.
printf("hello");
printf("\rbye ");
또는 먼저 몇 개의 공백을 사용하여 지운 다음 새 문자열을 인쇄하십시오.
printf("hello");
printf("\r ");
printf("\rbye");
즉 인쇄됩니다 안녕하세요 다시 처음으로 돌아가서 인쇄, 다음 줄의 시작 부분으로 이동 공간으로 덮어, 안녕 .
가치있는 미묘함 ...
\33[2K
현재 커서가있는 전체 줄을 지 웁니다.
\033[A
커서를 한 줄 위로 이동하지만 같은 열, 즉 줄의 시작 부분이 아닙니다.
\r
커서를 줄의 시작 부분으로 가져 오지만 (r은 되감기) 아무것도 지우지 않습니다 .
특히 xterm에서는 위에서 언급 한 답변을 시도했으며 줄을 지우고 처음부터 다시 시작하는 유일한 방법은 시퀀스입니다 (@ Stephan202와 @vlp 및 @mantal이 게시 한 위의 주석에서) \33[2K\r
구현 메모에서 예를 들어 카운트 다운 시나리오에서 제대로 작동하도록하려면 '\n'
각 끝에 줄 바꿈 문자 를 사용하지 않았기 fprintf()
때문에 fflush()
매번 스트림으로 이동 해야했습니다 (일부 컨텍스트를 제공하기 위해 xterm은 stdout을 리디렉션하지 않고 Linux 시스템에서 포크를 사용하여 버퍼링 된 FILE 포인터 fdfile
에 비 블로킹 파일 설명자를 사용하여 필자의 경우 의사 터미널 주소에 앉아있었습니다. /dev/pts/21
)
fprintf(fdfile, "\33[2K\rT minus %d seconds...", i);
fflush(fdfile);
줄을 지우는 데 \ 33 [2K 시퀀스를 모두 사용하고 줄 \r
의 시작 부분에 커서를 재배치하기 위해 되감기 시퀀스를 사용했습니다. 나는 끝에 줄 바꿈 문자가 없기 때문에 fflush()
매번마다 fprintf()
해야했습니다 '\n'
. fflush ()가 필요없는 동일한 결과는 한 줄 위로 올라 가기 위해 추가 시퀀스가 필요합니다.
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);
}
\ b를 사용하여 줄을 삭제할 수 있습니다.
printf("hello");
int i;
for (i=0; i<80; i++)
{
printf("\b");
}
printf("bye");
일반적으로 문자열 끝에 '\ r'이 있으면 개행없이 캐리지 리턴 만 인쇄됩니다. 다음이있는 경우 :
printf("fooooo\r");
printf("bar");
출력은 다음과 같습니다.
barooo
내가 제안 할 수있는 한 가지 (해결 방법 일 수 있음)는 모든 공백 문자로 초기화되고 '\ r'(인쇄 전 매번)로 끝나는 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
항상 길이가 .NET보다 적어도 하나 짧아 str
지지만 기본 아이디어를 얻을 수 있습니다.
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;
}
이 스크립트는 예제를 위해 하드 코딩되었습니다.
#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;
}
소스를 보려면 여기를 클릭하십시오 .
여기에서 작업 할 수있는 간단한 트릭이 있지만 인쇄하기 전에 준비가 필요합니다. 인쇄하려는 내용을 변수에 넣은 다음 인쇄하여 문자열을 제거 할 길이를 알아야합니다. 여기에 예제가 있습니다.
#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 ;
}
}
방금이 오래된 스레드를 찾았고 실제 줄을 비울 어떤 종류의 이스케이프 시퀀스를 찾습니다.
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 초 동안 대기합니다 (슬립 1).
그런 다음 hello를 bye로 대체합니다 (\ r 사용).
NOTE : Using ";", We can run multiple command in a single go.
under windows 10 one can use VT100 style by activating the VT100 mode in the current console to use escape sequences as follow :
#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 ....";
}
}
see following link : windows VT100
참고URL : https://stackoverflow.com/questions/1508490/erase-the-current-printed-console-line
'program tip' 카테고리의 다른 글
자바 : for (;;) 대 while (true) (0) | 2020.12.03 |
---|---|
치명적 오류 : 부울에서 멤버 함수 bind_param () 호출 (0) | 2020.12.03 |
Private Sub, Function 및 Class의 차이점 (0) | 2020.12.03 |
히스토그램 아래의 직사각형 영역 최대화 (0) | 2020.12.03 |
csv 데이터를 가져올 때 "UTF-8에서 잘못된 바이트 시퀀스"를 제거하는 방법 (0) | 2020.12.03 |