C# - 无法根据文本文件数据在列表中添加元素(这是一个列表)
C# - Unable to add elements (which is a list) in a list according to text file data
我正在开发 C# winForm 应用程序。在我的项目中,我需要读取文本文件。并获取列表中的数据。
对于测试:使用 "listTest" 列表
对于 cmd : 使用 "listCmd" 列表
我的要求是:我需要 mainList 中的 Test1 和 Test2 "listTest"。在 Test1 -> cmd1、cmd2、cmd3(在 listCmd 中)。在 cmd1 -> tx,rx 中。与 Test2 相同。
文本文件数据
Test:Test1
cmd-1:5A 02 11 00 02 3A 05 ||5A 02 01 02 3A 3F
cmd-2:5A 02 31 00 02 3E 00 80||5A 02 01 02 3E 43
cmd-3:5A 02 21 00 02 00||5A 02 01 02 0B 10
Test:Test2
cmd-1:5A 02 11 00 02 3A 05 00 14 00 42||5A 02 01 02 3A 3F
cmd-2:5A 02 31 00 02 3E 00 00 02 00 80||5A 02 01 02 3E 43
我的问题:我尝试了以下代码,其中,我得到了 Test1 的所有 5 个 cmd 值。 Test2 也一样。我只想要 Test1 中的 3 cmd 和 Test2 中的 2 cmd。
.
在class-1:
private void readCmd()
{
string cmdfile = System.IO.Directory.GetCurrentDirectory() + "\Cmd.txt";
try
{
string[] lines = File.ReadAllLines(cmdfile);
string[] splitLine;
string[] txRx;
cls_test testnum = new cls_test();
str_listcmd listcmd = new str_listcmd();
foreach (string line in lines)
{
if (line.Contains("Test"))
{
splitLine = line.Split(':');
txRx = splitLine.Skip(1).ToArray();
uc.listTest.Add(testnum);
}
if (line.Contains("cmd"))
{
string[] delimiter = { ":", "||" };
txRx = line.Split(delimiter, StringSplitOptions.None);
listcmd.cmdNo = txRx[0];
listcmd.txCmd = txRx[1];
listcmd.rxCmd = txRx[2];
testnum.listCmd.Add(listcmd);
}
}
for (int j = 0; j < uc.listTest.Count; j++)
{
for (int i = 0; i < uc.listTest[j].listCmd.Count; i++)
{
string tx = uc.listTest[j].listCmd[i].txCmd;
string rx = uc.listTest[j].listCmd[i].rxCmd;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
在Class-2中,声明了主列表
public List<cls_test> listTest = new List<cls_test>(); //main list
struct str_listcmd
{
public string cmdNo { get; set; }
public string txCmd { get; set; }
public string rxCmd { get; set; }
}
class cls_test
{
public List<str_listcmd> listCmd = new List<str_listcmd>();
}
private void button1_Click(object sender, EventArgs e)
{
var a = listTest;
}
我找不到我遗漏的东西。请帮我解决这个问题。提前致谢。
事实上,您可以重构代码以使其更加结构化,从而减少潜在错误并提高可测试性。为了解决您当前的问题,只需更换如下代码即可;
// ...
// ...
cls_test testnum = null; // <= Leave as NULL at the beginning
str_listcmd listcmd = new str_listcmd();
foreach (string line in lines)
{
if (line.Contains("Test"))
{
testnum = new cls_test(); // <= Init object for each Test line
// ...
// ...
当你读一个cmd时,你总是把它赋值给testnum
testnum.listCmd.Add(listcmd);
但是当您阅读 "Test" 行时,您不会创建新的测试编号,因此所有 cmd 都会分配给同一个测试。
我认为测试线部分应该如下所示:
if (line.Contains("Test"))
{
splitLine = line.Split(':');
txRx = splitLine.Skip(1).ToArray();
testnum = new cls_test();
uc.listTest.Add(testnum);
}
我不确定为什么这部分会更改 txRx。
总的来说,这是相当混乱的代码。我认为您应该在循环内移动 splitLine、rxTx 和 listCmd,以表明它们的值不会从一行转移到下一行。
我正在开发 C# winForm 应用程序。在我的项目中,我需要读取文本文件。并获取列表中的数据。
对于测试:使用 "listTest" 列表
对于 cmd : 使用 "listCmd" 列表
我的要求是:我需要 mainList 中的 Test1 和 Test2 "listTest"。在 Test1 -> cmd1、cmd2、cmd3(在 listCmd 中)。在 cmd1 -> tx,rx 中。与 Test2 相同。
文本文件数据
Test:Test1
cmd-1:5A 02 11 00 02 3A 05 ||5A 02 01 02 3A 3F
cmd-2:5A 02 31 00 02 3E 00 80||5A 02 01 02 3E 43
cmd-3:5A 02 21 00 02 00||5A 02 01 02 0B 10
Test:Test2
cmd-1:5A 02 11 00 02 3A 05 00 14 00 42||5A 02 01 02 3A 3F
cmd-2:5A 02 31 00 02 3E 00 00 02 00 80||5A 02 01 02 3E 43
我的问题:我尝试了以下代码,其中,我得到了 Test1 的所有 5 个 cmd 值。 Test2 也一样。我只想要 Test1 中的 3 cmd 和 Test2 中的 2 cmd。 .
在class-1:
private void readCmd()
{
string cmdfile = System.IO.Directory.GetCurrentDirectory() + "\Cmd.txt";
try
{
string[] lines = File.ReadAllLines(cmdfile);
string[] splitLine;
string[] txRx;
cls_test testnum = new cls_test();
str_listcmd listcmd = new str_listcmd();
foreach (string line in lines)
{
if (line.Contains("Test"))
{
splitLine = line.Split(':');
txRx = splitLine.Skip(1).ToArray();
uc.listTest.Add(testnum);
}
if (line.Contains("cmd"))
{
string[] delimiter = { ":", "||" };
txRx = line.Split(delimiter, StringSplitOptions.None);
listcmd.cmdNo = txRx[0];
listcmd.txCmd = txRx[1];
listcmd.rxCmd = txRx[2];
testnum.listCmd.Add(listcmd);
}
}
for (int j = 0; j < uc.listTest.Count; j++)
{
for (int i = 0; i < uc.listTest[j].listCmd.Count; i++)
{
string tx = uc.listTest[j].listCmd[i].txCmd;
string rx = uc.listTest[j].listCmd[i].rxCmd;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
在Class-2中,声明了主列表
public List<cls_test> listTest = new List<cls_test>(); //main list
struct str_listcmd
{
public string cmdNo { get; set; }
public string txCmd { get; set; }
public string rxCmd { get; set; }
}
class cls_test
{
public List<str_listcmd> listCmd = new List<str_listcmd>();
}
private void button1_Click(object sender, EventArgs e)
{
var a = listTest;
}
我找不到我遗漏的东西。请帮我解决这个问题。提前致谢。
事实上,您可以重构代码以使其更加结构化,从而减少潜在错误并提高可测试性。为了解决您当前的问题,只需更换如下代码即可;
// ...
// ...
cls_test testnum = null; // <= Leave as NULL at the beginning
str_listcmd listcmd = new str_listcmd();
foreach (string line in lines)
{
if (line.Contains("Test"))
{
testnum = new cls_test(); // <= Init object for each Test line
// ...
// ...
当你读一个cmd时,你总是把它赋值给testnum
testnum.listCmd.Add(listcmd);
但是当您阅读 "Test" 行时,您不会创建新的测试编号,因此所有 cmd 都会分配给同一个测试。
我认为测试线部分应该如下所示:
if (line.Contains("Test"))
{
splitLine = line.Split(':');
txRx = splitLine.Skip(1).ToArray();
testnum = new cls_test();
uc.listTest.Add(testnum);
}
我不确定为什么这部分会更改 txRx。
总的来说,这是相当混乱的代码。我认为您应该在循环内移动 splitLine、rxTx 和 listCmd,以表明它们的值不会从一行转移到下一行。