C# 控制台 - 如何在没有新行的情况下读取 ReadLine()? (或撤消 \n 或垂直 \b)
C# Console - How to ReadLine() without a new line? ( or undo a \n or a vertical \b)
我想知道当我在下一行的开头时是否可以回到最后一行? (当然是在 C# 控制台中)
我的意思是 Console.WriteLine()
因为要转到下一行,即使在按 enter 后我也想留在我的行中。 (而且我认为没有另一种方法可以不转到下一行就可以读取 ReadLine ,是吗?)
我发现 Console.SetCursorPosition()
很有用,如下所示:
int x, y;
Console.WriteLine("Please enter the point's coordinates in this form (x,y):");
Console.Write("(");
x = Convert.ToInt32(Console.ReadLine());
Console.SetCursorPosition(x.ToString().Length + 1, Console.CursorTop - 1);
Console.Write(",");
y = Convert.ToInt32(Console.ReadLine());
Console.SetCursorPosition(x.ToString().Length + y.ToString().Length + 2, Console.CursorTop - 1);
Console.WriteLine(")");
这似乎工作正常,但是当我尝试更改时 Console.Write("(")
;
变成类似 Console.Write("Point A=(")
的东西,我每次都需要更改 Console.SetCursorPosition()
参数。
如果我可以将光标移动到控制台缓冲区中的最后一个字符(空格除外),这将非常有帮助。(我认为如果我可以将特定行从控制台复制到字符串中会很容易。 )
提前致谢。
如何使用适合您的特定用例并有助于使您的代码逻辑更具可读性的简单助手 class。
public class Prompt
{
public struct CursorPosition
{
public int CursorLeft;
public int CursorTop;
}
private CursorPosition _savedPosition;
public Prompt Write(string prompt)
{
Console.Write(prompt);
return this;
}
public Prompt Write(string promptFormat, params object[] args)
{
return Write(string.Format(promptFormat, args));
}
public Prompt WriteLine(string prompt)
{
Write(prompt);
Console.WriteLine();
return this;
}
public Prompt WriteLine(string promptFormat, params object[] args)
{
return WriteLine(string.Format(promptFormat, args));
}
public string ReadLine(bool advanceCursorOnSameLine = false, bool eraseLine = false)
{
if (advanceCursorOnSameLine || eraseLine)
{
SavePosition();
if (eraseLine)
WriteLine(new string(' ', Console.WindowWidth - _savedPosition.CursorLeft)).RestorePosition();
}
var input = Console.ReadLine();
if (advanceCursorOnSameLine)
RestorePosition(input.Length);
return input;
}
public Prompt SavePosition()
{
_savedPosition = GetCursorPosition();
return this;
}
public CursorPosition GetCursorPosition()
{
return new CursorPosition {
CursorLeft = Console.CursorLeft,
CursorTop = Console.CursorTop
};
}
public Prompt RestorePosition(CursorPosition position, int deltaLeft = 0, int deltaTop = 0)
{
var left = Math.Min(Console.BufferWidth - 1, Math.Max(0, position.CursorLeft + deltaLeft));
var right = Math.Min(Console.BufferHeight - 1, Math.Max(0, position.CursorTop + deltaTop));
Console.SetCursorPosition(left, right);
return this;
}
public Prompt RestorePosition(int deltaLeft = 0, int deltaTop = 0)
{
return RestorePosition(_savedPosition, deltaLeft, deltaTop);
}
}
然后可以这样使用:
class Program
{
public static void Main(params string[] args)
{
int x, y;
var prompt = new Prompt();
prompt.WriteLine("Please enter the point's coordinates in this form (x,y):");
var savedPos = prompt.GetCursorPosition();
while (true)
{
x = Convert.ToInt32(prompt.Write("(").ReadLine(true, true));
y = Convert.ToInt32(prompt.Write(",").ReadLine(true));
prompt.WriteLine(")");
// do something with x and y
var again = prompt.Write("More (Y):").ReadLine(true, true);
if (!again.StartsWith("Y", StringComparison.OrdinalIgnoreCase))
break;
prompt.RestorePosition(savedPos);
}
}
}
我想知道当我在下一行的开头时是否可以回到最后一行? (当然是在 C# 控制台中)
我的意思是 Console.WriteLine()
因为要转到下一行,即使在按 enter 后我也想留在我的行中。 (而且我认为没有另一种方法可以不转到下一行就可以读取 ReadLine ,是吗?)
我发现 Console.SetCursorPosition()
很有用,如下所示:
int x, y;
Console.WriteLine("Please enter the point's coordinates in this form (x,y):");
Console.Write("(");
x = Convert.ToInt32(Console.ReadLine());
Console.SetCursorPosition(x.ToString().Length + 1, Console.CursorTop - 1);
Console.Write(",");
y = Convert.ToInt32(Console.ReadLine());
Console.SetCursorPosition(x.ToString().Length + y.ToString().Length + 2, Console.CursorTop - 1);
Console.WriteLine(")");
这似乎工作正常,但是当我尝试更改时 Console.Write("(")
;
变成类似 Console.Write("Point A=(")
的东西,我每次都需要更改 Console.SetCursorPosition()
参数。
如果我可以将光标移动到控制台缓冲区中的最后一个字符(空格除外),这将非常有帮助。(我认为如果我可以将特定行从控制台复制到字符串中会很容易。 )
提前致谢。
如何使用适合您的特定用例并有助于使您的代码逻辑更具可读性的简单助手 class。
public class Prompt
{
public struct CursorPosition
{
public int CursorLeft;
public int CursorTop;
}
private CursorPosition _savedPosition;
public Prompt Write(string prompt)
{
Console.Write(prompt);
return this;
}
public Prompt Write(string promptFormat, params object[] args)
{
return Write(string.Format(promptFormat, args));
}
public Prompt WriteLine(string prompt)
{
Write(prompt);
Console.WriteLine();
return this;
}
public Prompt WriteLine(string promptFormat, params object[] args)
{
return WriteLine(string.Format(promptFormat, args));
}
public string ReadLine(bool advanceCursorOnSameLine = false, bool eraseLine = false)
{
if (advanceCursorOnSameLine || eraseLine)
{
SavePosition();
if (eraseLine)
WriteLine(new string(' ', Console.WindowWidth - _savedPosition.CursorLeft)).RestorePosition();
}
var input = Console.ReadLine();
if (advanceCursorOnSameLine)
RestorePosition(input.Length);
return input;
}
public Prompt SavePosition()
{
_savedPosition = GetCursorPosition();
return this;
}
public CursorPosition GetCursorPosition()
{
return new CursorPosition {
CursorLeft = Console.CursorLeft,
CursorTop = Console.CursorTop
};
}
public Prompt RestorePosition(CursorPosition position, int deltaLeft = 0, int deltaTop = 0)
{
var left = Math.Min(Console.BufferWidth - 1, Math.Max(0, position.CursorLeft + deltaLeft));
var right = Math.Min(Console.BufferHeight - 1, Math.Max(0, position.CursorTop + deltaTop));
Console.SetCursorPosition(left, right);
return this;
}
public Prompt RestorePosition(int deltaLeft = 0, int deltaTop = 0)
{
return RestorePosition(_savedPosition, deltaLeft, deltaTop);
}
}
然后可以这样使用:
class Program
{
public static void Main(params string[] args)
{
int x, y;
var prompt = new Prompt();
prompt.WriteLine("Please enter the point's coordinates in this form (x,y):");
var savedPos = prompt.GetCursorPosition();
while (true)
{
x = Convert.ToInt32(prompt.Write("(").ReadLine(true, true));
y = Convert.ToInt32(prompt.Write(",").ReadLine(true));
prompt.WriteLine(")");
// do something with x and y
var again = prompt.Write("More (Y):").ReadLine(true, true);
if (!again.StartsWith("Y", StringComparison.OrdinalIgnoreCase))
break;
prompt.RestorePosition(savedPos);
}
}
}