我正在构建C#控制台应用程序,从serialPort读取设备名称。我设法将所有连接的设备名称打印到控制台。控制台的输出是这样的。
Scanning...
---------------------------------
Connected devices:
1. DeviceName1
2. DeviceName2
3. DeviceName3
现在,如何从下往上读输出,直到第一个空行?比起有 Console.ReadLine()
让用户可以通过在deviceName前面输入数字来选择设备。
以下是我正在使用的代码。
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);
当你从串口读取时,你可以把它存储在一个字符串变量中。
然后根据换行符将字符串变量分割成一个数组进行处理。
对数组项进行迭代,只取那些以数字开头的,用句号隔开。
那些你想要的行,将它存储到Dictionary中,使用由 ReadExisting()
方法作为你的Dictionary索引,这是为了让你给设备分配一个ID,这样当用户选择ID时,你就可以通过它的ID反向查找设备。
然后,循环Dictionary将设备显示在控制台。
采集用户选择的ID,然后用字典通过ID反向查找设备。
我假设你有办法访问Enumerable列表中的设备列表。
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];
}