问题
I am trying to code a program to read out user-groups from a .txt-file and to put said groups into a listbox. An example for a group list would be the following:
User
-------------
Group1
Group2
Group3
[space]
[space]
next user
Every user has is in an unknown amount of groups, thats why there are two spaces, just to seperate everything.
Here is my progress so far:
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);
}
}
}
}
I really hope you can help me.
EDIT
This question has been answered, so there is no need for mor answers. Thanks for all the comments :)
回答1:
Your problem is, when the line for the user is found, you test if line == " " without proceeding to the next and your while loop should exit immediately then
Use for loop instead of for each. Have your while loop when you find the line for user as the same, and increase the loop variable with ++ inside the while loop and read the next line. Don't forget to check for the string array length before setting line = fileLines[lineIndex]
Therefore, here is the code that should work for you
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;
}
}
However, if the file is huge, you might want not to read all it's lines into memory, here is another approach which works with 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;
}
}
来源:https://stackoverflow.com/questions/33933153/reading-specific-lines-with-unknown-placement-in-c-sharp