programing

콘솔 텍스트의 이전 줄을 수정하는 방법은 무엇입니까?

cafebook 2023. 8. 26. 12:16
반응형

콘솔 텍스트의 이전 줄을 수정하는 방법은 무엇입니까?

저는 다음과 같은 목표를 달성하고 싶습니다.

Time consuming operation...OK
Another time consuming operation...
And another one, but it completed, so...OK

저는 3줄의 텍스트를 표시했는데, 각각은 조만간 끝날 수 있는 스레드와 관련이 있습니다.하지만 두 번째 것이 세 번째 것보다 나중에 완료되면 다음과 같은 것을 얻을 수 있습니다.

Time consuming operation...OK
Another time consuming operation...
And another one, but it completed, so...OKOK

물론 용납할 수 없는 일입니다.현재 줄로 돌아가는 방법은 알고 있는데 올라가는 방법이 있나요?리눅스 콘솔일 수도 있지만 어딘가에서 본 적이 있다고 맹세합니다 :)

잊어 버리세요.원격 파일 관리자를 참조하십시오!Windows 콘솔에서 작동하며 PowerShell에서도 작동합니다!이런 거 어떻게 만드는 거예요?가장 멋진 부분은 종료 후 콘솔 상태를 복원하는 것입니다.그래서 콘솔 버퍼에 직접 액세스하는 방법을 물어봐야 할 것 같습니다.속임수를 쓰려면 네이티브 코드가 필요할 것 같은데, 다른 방법이 있을까요?매번 업데이트할 때마다 콘솔을 지울 생각이었는데, 이건 너무 지나친 것 같습니다.아니면 아닌가요?깜빡일까요?

원하는 위치로 커서를 이동할 수 있습니다.콘솔.커서 위치를 설정하거나 콘솔을 사용합니다.커서 맨 위.

Console.SetCursorPosition(0, Console.CursorTop -1);
Console.WriteLine("Over previous line!!!");

캐리지 리턴을 사용합니다.이 샘플은 한 줄을 인쇄하여 이전에 있었던 것을 덮어씁니다.

  Console.WriteLine();
  for (int i = 0; i <= 100; i++)
  {
    System.Threading.Thread.Sleep(10);
    Console.Write("\x000DProgress: " + i);
  }

이것은 모든 문자열이 80열 미만인 경우(또는 터미널 버퍼가 설정된 경우) 작동합니다.

참고: 다음 답변은 원래 OP가 질문으로 편집한 것입니다.


데모가 포함된 완벽한 솔루션은 다음과 같습니다.

using System;
using System.Collections.Generic;
using System.Threading;

namespace PowerConsole {

    internal class Containers {

        internal struct Container {
            public int Id;
            public int X;
            public int Y;
            public string Content;
        }

        public static List<Container> Items = new List<Container>();

        private static int Identity = 0;

        public static int Add(string text) {
            var c = new Container();
            c.Id = Identity++;
            c.X = Console.CursorLeft;
            c.Y = Console.CursorTop;
            c.Content = text;
            Console.Write(text);
            Items.Add(c);
            return c.Id;
        }

        public static void Remove(int id) {
            Items.RemoveAt(id);
        }

        public static void Replace(int id, string text) {
            int x = Console.CursorLeft, y = Console.CursorTop;
            Container c = Items[id];
            Console.MoveBufferArea(
                c.X + c.Content.Length, c.Y,
                Console.BufferWidth - c.X - text.Length, 1,
                c.X + text.Length, c.Y
            );
            Console.CursorLeft = c.X;
            Console.CursorTop = c.Y;
            Console.Write(text);
            c.Content = text;
            Console.CursorLeft = x;
            Console.CursorTop = y;
        }

        public static void Clear() {
            Items.Clear();
            Identity = 0;
        }
    }

    internal class Program {
        private static List<Thread> Threads = new List<Thread>();

        private static void Main(string[] args) {
            Console.WriteLine("So we have some threads:\r\n");
            int i, id;
            Random r = new Random();
            for (i = 0; i < 10; i++) {
                Console.Write("Starting thread " + i + "...[");
                id = Containers.Add("?");
                Console.WriteLine("]");
                Thread t = new Thread((object data) => {
                    Thread.Sleep(r.Next(5000) + 100);
                    Console.ForegroundColor = ConsoleColor.Green;
                    Containers.Replace((int)data, "DONE");
                    Console.ResetColor();
                });
                Threads.Add(t);
            }
            Console.WriteLine("\n\"But will it blend?\"...");
            Console.ReadKey(true);
            i = 0;
            Threads.ForEach(t => t.Start(i++));
            Threads.ForEach(t => t.Join());
            Console.WriteLine("\r\nVoila.");
            Console.ReadKey(true);
        }
    }
}

언급URL : https://stackoverflow.com/questions/10804233/how-to-modify-the-previous-line-of-console-text

반응형