在 C# 中读取位置未知的特定行
Reading specific lines with unknown placement in C#
我正在尝试编写一个程序以从 .txt 文件中读出用户组并将所述组放入列表框中。组列表的示例如下:
用户
-------------
第 1 组
Group2
Group3
[space]
[space]
下一个用户
每个用户都在未知数量的组中,这就是为什么有两个 space,只是为了将所有内容分开。
这是我目前的进度:
private void Button_Click(object sender, RoutedEventArgs e) {
//users.txt contains all users
//in the same directory there are multiple lists with given groups
StreamReader sr = new StreamReader("c:\ADHistory\users.txt", System.Text.Encoding.Default);
string line = string.Empty;
try {
//Read the first line of text
line = sr.ReadLine();
//Continue to read until you reach end of file
while (line != null) {
listboxNames.Items.Add(line);
//Read the next line
line = sr.ReadLine();
}
//close the file
sr.Close();
}
catch (Exception f)
{
MessageBox.Show(f.Message.ToString());
}
finally
{
//close the file
sr.Close();
}
}
private void listboxNames_SelectionChanged(object sender, SelectionChangedEventArgs e) {
//as soon as you choose a user from the first list
//you may choose a date to look at all groups the user is in.
listboxDates.Items.Clear();
DirectoryInfo dinfo = new DirectoryInfo(@"C:\ADHistory");
FileInfo[] Files = dinfo.GetFiles("*.txt");
//this adds all dates into the second listbox
//and removes users.txt from the list.
foreach (FileInfo file in Files) {
listboxDates.Items.Add(file.Name);
}
for (int n = listboxDates.Items.Count - 1; n >= 0; --n)
{
string removelistitem = "users";
if (listboxDates.Items[n].ToString().Contains(removelistitem))
{
listboxDates.Items.RemoveAt(n);
}
//this displays the user below the listboxes,
//because of styling purposes
string user = Convert.ToString(this.listboxNames.SelectedItem);
labelName.Content = user;
}
}
//here we have my main problem.
//I can't find a solution to add the groups to the last listbox
private void listboxDates_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string user = Convert.ToString(labelName.Content);
listboxGroups.Items.Clear();
string path = "C:\ADHistory\";
path += Convert.ToString(this.listboxDates.SelectedItem);
foreach (string line in File.ReadLines(path))
{
if (line.Contains(user))
{
while (line != " ")
{
listboxGroups.Items.Add(line);
}
}
}
}
我真的希望你能帮助我。
编辑
这个问题已经回答了,就不用再回答了。
感谢所有评论:)
你的问题是,当找到用户所在的行时,你测试 if line == " " 而没有继续下一步,你的 while 循环应该立即退出
使用 for 循环而不是 for each。当您找到相同的用户行时,让您的 while 循环,并在 while 循环内用 ++ 增加循环变量并读取下一行。不要忘记在设置 line = fileLines[lineIndex]
之前检查字符串数组长度
因此,这是适合您的代码
string[] fileLines = File.ReadAllLines(path);
for (int lineIndex = 0; lineIndex < fileLines.Length; lineIndex++)
{
string line = fileLines[lineIndex];
if (line.Contains(user))
{
while(++lineIndex < fileLines.Length && (line = fileLines[lineIndex]) != " ")
{
listboxGroups.Items.Add(line);
}
break;
}
}
但是,如果文件很大,您可能不想将所有行都读入内存,这是另一种适用于 File.ReadLines()
的方法
IEnumerator<string> fileLines = File.ReadLines(path).GetEnumerator();
while (fileLines.MoveNext())
{
string line = fileLines.Current;
if (line.Contains(user))
{
while (fileLines.MoveNext())
{
line = fileLines.Current;
if (line == " ")
{
break;
}
listboxGroups.Items.Add(line);
}
break;
}
}
我正在尝试编写一个程序以从 .txt 文件中读出用户组并将所述组放入列表框中。组列表的示例如下:
用户
-------------
第 1 组
Group2
Group3
[space]
[space]
下一个用户
每个用户都在未知数量的组中,这就是为什么有两个 space,只是为了将所有内容分开。
这是我目前的进度:
private void Button_Click(object sender, RoutedEventArgs e) {
//users.txt contains all users
//in the same directory there are multiple lists with given groups
StreamReader sr = new StreamReader("c:\ADHistory\users.txt", System.Text.Encoding.Default);
string line = string.Empty;
try {
//Read the first line of text
line = sr.ReadLine();
//Continue to read until you reach end of file
while (line != null) {
listboxNames.Items.Add(line);
//Read the next line
line = sr.ReadLine();
}
//close the file
sr.Close();
}
catch (Exception f)
{
MessageBox.Show(f.Message.ToString());
}
finally
{
//close the file
sr.Close();
}
}
private void listboxNames_SelectionChanged(object sender, SelectionChangedEventArgs e) {
//as soon as you choose a user from the first list
//you may choose a date to look at all groups the user is in.
listboxDates.Items.Clear();
DirectoryInfo dinfo = new DirectoryInfo(@"C:\ADHistory");
FileInfo[] Files = dinfo.GetFiles("*.txt");
//this adds all dates into the second listbox
//and removes users.txt from the list.
foreach (FileInfo file in Files) {
listboxDates.Items.Add(file.Name);
}
for (int n = listboxDates.Items.Count - 1; n >= 0; --n)
{
string removelistitem = "users";
if (listboxDates.Items[n].ToString().Contains(removelistitem))
{
listboxDates.Items.RemoveAt(n);
}
//this displays the user below the listboxes,
//because of styling purposes
string user = Convert.ToString(this.listboxNames.SelectedItem);
labelName.Content = user;
}
}
//here we have my main problem.
//I can't find a solution to add the groups to the last listbox
private void listboxDates_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string user = Convert.ToString(labelName.Content);
listboxGroups.Items.Clear();
string path = "C:\ADHistory\";
path += Convert.ToString(this.listboxDates.SelectedItem);
foreach (string line in File.ReadLines(path))
{
if (line.Contains(user))
{
while (line != " ")
{
listboxGroups.Items.Add(line);
}
}
}
}
我真的希望你能帮助我。
编辑
这个问题已经回答了,就不用再回答了。 感谢所有评论:)
你的问题是,当找到用户所在的行时,你测试 if line == " " 而没有继续下一步,你的 while 循环应该立即退出
使用 for 循环而不是 for each。当您找到相同的用户行时,让您的 while 循环,并在 while 循环内用 ++ 增加循环变量并读取下一行。不要忘记在设置 line = fileLines[lineIndex]
之前检查字符串数组长度因此,这是适合您的代码
string[] fileLines = File.ReadAllLines(path);
for (int lineIndex = 0; lineIndex < fileLines.Length; lineIndex++)
{
string line = fileLines[lineIndex];
if (line.Contains(user))
{
while(++lineIndex < fileLines.Length && (line = fileLines[lineIndex]) != " ")
{
listboxGroups.Items.Add(line);
}
break;
}
}
但是,如果文件很大,您可能不想将所有行都读入内存,这是另一种适用于 File.ReadLines()
的方法IEnumerator<string> fileLines = File.ReadLines(path).GetEnumerator();
while (fileLines.MoveNext())
{
string line = fileLines.Current;
if (line.Contains(user))
{
while (fileLines.MoveNext())
{
line = fileLines.Current;
if (line == " ")
{
break;
}
listboxGroups.Items.Add(line);
}
break;
}
}