C# 从下到上读取控制台输出,直到空行
C# Read console output from bottom to top, until empty line
我正在构建 C# 控制台应用程序以从串行端口读取设备名称。我设法将所有连接的设备名称打印到控制台。控制台输出如下所示:
Scanning...
---------------------------------
Connected devices:
1. DeviceName1
2. DeviceName2
3. DeviceName3
现在,如何从下到上读取输出,直到第一个空行?比 Console.ReadLine()
让用户可以通过在设备名称前键入数字来选择设备。
这是我使用的代码:
var serialPort = new System.IO.Ports.SerialPort()
// Read the data that's in the serial buffer.
var deviceName = serialPort.ReadExisting();
// Write to debug output.
Console.WriteLine($"\n---------------------------------");
Console.WriteLine($"\nConnected devices:\n");
Console.WriteLine(deviceName);
string input;
do
{
// Here I need posibility for user
// to type number infront deviceName
} while (deviceName.ToUpper() != null);
当你从串口读取时,你可以将它存储在一个字符串变量中。
然后根据换行符将字符串变量拆分成一个数组来处理它。
遍历数组项,只取那些以数字开头、用句号分隔的项。
那些你想要的行,将它存储到字典中,使用ReadExisting()
方法提供的索引作为你的字典索引。
这是为了让你给设备分配一个ID,这样当用户select这个ID时,你可以通过它的ID反向查找设备。
然后,循环字典以将设备显示到控制台。
抓取用户select输入的ID,然后根据ID使用字典反向查找设备。
我假设您有办法访问可枚举列表中的设备列表。
public static void Main(string[] args)
{
// Can't simulate the output. So, I assume there is an output from ReadExisting(), and I capture the output to a string variable.
// var serialPort = new System.IO.Ports.SerialPort();
// var outputReadExisting = serialPort.ReadExisting();
var outputReadExisting = @"Scanning...
-------------------------------- -
Connected devices:
1.DeviceName1
2.DeviceName2
3.DeviceName3";
var deviceDict = LoadDevicesToDictionary(outputReadExisting);
DisplayDevices(deviceDict);
var selectedDevice = PromptUserToSelectDevice(deviceDict);
}
private static Dictionary<int, string> LoadDevicesToDictionary(string output)
{
var outputLines = output.Split(new[] { Environment.NewLine, "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
var deviceDict = new Dictionary<int, string>();
foreach (var line in outputLines)
{
// Skip line if null/whitespace or if it does not contains "." (the index)
if (string.IsNullOrWhiteSpace(line) || !line.Contains("."))
{
continue;
}
var splitLine = line.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
// Skip line if after splitting by number and first part is not an integer (not device index)
if (splitLine.Length < 2 || !int.TryParse(splitLine[0], out var deviceIndex))
{
continue;
}
// Add device index as dictionary index, then take remainder string minus the device index and the "."
deviceDict.Add(deviceIndex, line.Substring(deviceIndex.ToString().Length + 1));
}
return deviceDict;
}
private static void DisplayDevices(Dictionary<int, string> deviceDict)
{
foreach (var device in deviceDict)
{
Console.WriteLine($"{device.Key}. {device.Value}");
}
}
private static string PromptUserToSelectDevice(Dictionary<int, string> deviceDict)
{
Console.WriteLine("Please select your device (ID): ");
var selectedId = Console.ReadLine();
if (!int.TryParse(selectedId, out var idVal)
|| !deviceDict.ContainsKey(idVal))
{
Console.WriteLine("Invalid input. Please input device ID listed above.");
return PromptUserToSelectDevice(deviceDict);
}
return deviceDict[idVal];
}
我正在构建 C# 控制台应用程序以从串行端口读取设备名称。我设法将所有连接的设备名称打印到控制台。控制台输出如下所示:
Scanning...
---------------------------------
Connected devices:
1. DeviceName1
2. DeviceName2
3. DeviceName3
现在,如何从下到上读取输出,直到第一个空行?比 Console.ReadLine()
让用户可以通过在设备名称前键入数字来选择设备。
这是我使用的代码:
var serialPort = new System.IO.Ports.SerialPort()
// Read the data that's in the serial buffer.
var deviceName = serialPort.ReadExisting();
// Write to debug output.
Console.WriteLine($"\n---------------------------------");
Console.WriteLine($"\nConnected devices:\n");
Console.WriteLine(deviceName);
string input;
do
{
// Here I need posibility for user
// to type number infront deviceName
} while (deviceName.ToUpper() != null);
当你从串口读取时,你可以将它存储在一个字符串变量中。
然后根据换行符将字符串变量拆分成一个数组来处理它。
遍历数组项,只取那些以数字开头、用句号分隔的项。
那些你想要的行,将它存储到字典中,使用ReadExisting()
方法提供的索引作为你的字典索引。
这是为了让你给设备分配一个ID,这样当用户select这个ID时,你可以通过它的ID反向查找设备。
然后,循环字典以将设备显示到控制台。
抓取用户select输入的ID,然后根据ID使用字典反向查找设备。
我假设您有办法访问可枚举列表中的设备列表。
public static void Main(string[] args)
{
// Can't simulate the output. So, I assume there is an output from ReadExisting(), and I capture the output to a string variable.
// var serialPort = new System.IO.Ports.SerialPort();
// var outputReadExisting = serialPort.ReadExisting();
var outputReadExisting = @"Scanning...
-------------------------------- -
Connected devices:
1.DeviceName1
2.DeviceName2
3.DeviceName3";
var deviceDict = LoadDevicesToDictionary(outputReadExisting);
DisplayDevices(deviceDict);
var selectedDevice = PromptUserToSelectDevice(deviceDict);
}
private static Dictionary<int, string> LoadDevicesToDictionary(string output)
{
var outputLines = output.Split(new[] { Environment.NewLine, "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
var deviceDict = new Dictionary<int, string>();
foreach (var line in outputLines)
{
// Skip line if null/whitespace or if it does not contains "." (the index)
if (string.IsNullOrWhiteSpace(line) || !line.Contains("."))
{
continue;
}
var splitLine = line.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
// Skip line if after splitting by number and first part is not an integer (not device index)
if (splitLine.Length < 2 || !int.TryParse(splitLine[0], out var deviceIndex))
{
continue;
}
// Add device index as dictionary index, then take remainder string minus the device index and the "."
deviceDict.Add(deviceIndex, line.Substring(deviceIndex.ToString().Length + 1));
}
return deviceDict;
}
private static void DisplayDevices(Dictionary<int, string> deviceDict)
{
foreach (var device in deviceDict)
{
Console.WriteLine($"{device.Key}. {device.Value}");
}
}
private static string PromptUserToSelectDevice(Dictionary<int, string> deviceDict)
{
Console.WriteLine("Please select your device (ID): ");
var selectedId = Console.ReadLine();
if (!int.TryParse(selectedId, out var idVal)
|| !deviceDict.ContainsKey(idVal))
{
Console.WriteLine("Invalid input. Please input device ID listed above.");
return PromptUserToSelectDevice(deviceDict);
}
return deviceDict[idVal];
}