【问题标题】:Read text file, split and use arrays to display elements in labels读取文本文件,拆分并使用数组在标签中显示元素
【发布时间】:2015-04-03 02:07:07
【问题描述】:

我的 C# Windows 窗体应用程序有问题。我有一个格式为 - LastName,FirstName,MiddleName,DateOfEnrolment,Gender 的文本文件,如下所示:

博客,乔,约翰,2015/01/04,M

文本文件中有 10 行。

我想读入文本文件,分割每一行并将每个元素放入一个数组中。然后每个元素将被放置到它自己的标签中。有一个名为 open 的按钮用于打开文本文件,然后有一个名为 first 的按钮以在其各个标签中显示第一行的元素。有一个名为 previous 的按钮可以转到上一行,下一个按钮可以转到下一行,最后一个按钮可以转到最后一行,再次在标签中显示所选行的元素。v以下代码是我已经拥有的,但是btnFirst_Click 全部显示为红色。

请帮忙!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace Assignment1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public class SR
{
public string lastName;
public string firstName;
public string middleName;
public string date;
public string gender;
}
private void btnOpen_Click(object sender, EventArgs e)
{
List<SR> studentRecords = new List<SR>();
string file_name = (@"C:\Users\StudentRecords.txt");

StreamReader objReader = new StreamReader(file_name);
objReader = new StreamReader(file_name);

int counter = 0;
string line;
while ((line = objReader.ReadLine()) != null)
{
listBox.Items.Add(line);
counter++;
}

{
while (objReader.Peek() >= 0)
{
string str;
string[] strArray;
str = objReader.ReadLine();

strArray = str.Split(',');
SR currentSR = new SR();
currentSR.lastName = strArray[0];
currentSR.firstName = strArray[1];
currentSR.middleName = strArray[2];
currentSR.date = strArray[3];
currentSR.gender = strArray[4];

studentRecords.Add(currentSR);
}
}
objReader.Close();
}

private void btnFirst_Click(object sender, EventArgs e)
{
lblFN.Text = strArray[1];
lblMN.Text = strArray[2];
lblLN.Text = strArray[0];
lblDoE.Text = strArray[3];
lblGen.Text = strArray[4];
}

【问题讨论】:

  • 嗯,当然。 strArray 是你的 btnOpen_Click 方法中的一个局部变量(实际上它甚至是你的 while 循环体的局部变量)。您无法从其他方法读取局部变量。即使可以,每次循环时都会获得该变量的新副本;你想要哪一个?弄清楚这一点,并将其放入字段而不是局部变量中。
  • 它显示为红色,因为您将 strArray 变量创建为局部变量而不是类属性。
  • Joe White... 我希望数组的元素(姓氏、名字、中间名等)形成一个数组。单击第一个按钮时,在其自己的标签中显示第一行的元素。然后,当单击下一个按钮时,转到下一行,依此类推。上一个按钮转到上一行等,最后一个按钮再次转到文本文件的最后一行,所有元素都显示在自己的标签中

标签: c# arrays button


【解决方案1】:

您的strArraybtnOpen_Click 方法内的循环中定义。因此,尝试从btnFirst_Click 访问它是行不通的。您需要将 strArray 的声明移到方法之外,以使其在两个方法中都可以访问。

尝试将其移至类定义的顶部,如下所示:

namespace Assignment1
{
    public partial class Form1 : Form
    {
        private string[] strArray;  // <---------- here is your array
        public Form1()
        {
            InitializeComponent();
        }
        ...

然后您可以从btnOpen_ClickbtnFirst_Click 访问该数组。

【讨论】:

  • 它会出现以下错误:“错误的数组声明符。要声明托管数组,排名说明符位于变量标识符之前。要声明固定大小的缓冲区字段,请在字段类型之前使用 fixed 关键字”。我不明白
  • 糟糕,应该是这样的:private string[] strArray;
【解决方案2】:

首先,真正需要嵌套类的情况很少见,所以.. (使用完整的类名,不需要偷懒,并且几乎不要使用公共字段,使用属性(大写)。

public class StudentRecord
{
  public string LastName { get; set;} 
  public string FirstName { get; set;}
  public string MiddleName { get; set;}
  public string Date { get; set;}
  public string Gender { get; set;}
}

public partial class Form1 : Form
{
  public Form1()
  {
    InitializeComponent();
  }
  // ....
}

其次,避免使用数组(恕我直言):

public partial class Form1 : Form
{
  // initialize list to zero, we'll reset everytime
  // we load students.  Also a null list will
  // throw an error below the way I have it coded.
  private List<StudentRecord> _studentRecords = new List<StudentRecord>(0);
  // ..
}

避免实际将逻辑放入btnOpen_Click 方法中:

private void btnOpen_Click(object sender, EventArgs e)
{
  LoadStudentRecords();
}

读取文件的简单方法:

private void LoadStudentRecords()
{
  // reset the list to empty, so we don't always append to existing
  _studentRecords = new List<StudentRecord>();
  string file_name = (@"C:\Users\StudentRecords.txt");
  var lines = File.ReadAllLines(file_name).ToList();
  foreach(var line in lines)
  {
    var studentRecord = ParseStudentRecordLine(line);
    if (studentRecord != null)
    {
      _studentRecords.Add(studentRecord);
    }
  }
}

将逻辑分离为逻辑方法:

public StudentRecord ParseStudentRecordLine(string line)
{
  SR result = null;

  // error check line, don't want to blow up
  if (!string.IsNullOrWhiteSpace(line))
  {
    var values = line.Split(',');
    // error values length, don't want to blow up
    if (values.Length == 5) // or > 4
    {
      var result = new StudentRecord();
      result.lastName = values [0];
      result.firstName = values [1];
      result.middleName = values [2];
      result.date = values [3];
      result.gender = values [4];
    }
  }

  return result;
}

最后分配它们:

private void ShowStudent(StudentRecord studentRecord)
{
  // what if we haven't loaded student records
  // and someone tried to show one?
  if (studentRecord != null)
  {
    lblFN.Text = studentRecord.FirstName;
    lblMN.Text = studentRecord.MiddleName;
    lblLN.Text = studentRecord.LastName;
    lblDoE.Text = studentRecord.Date;
    lblGen.Text = studentRecord.Gender;

    _currentStudentRecordIndex = _studentRecords.IndexOf(studentRecord);
  }
  else
  {
    // Show error msg "No students to show, maybe load students first"
  }
}

有一个按钮叫previous去上一行,next按钮去下一行,last按钮去最后一行,

所以你想保留当前元素的索引。将索引添加到表单中:

public partial class Form1 : Form
{
  private List<StudentRecord> _studentRecords = new List<StudentRecord>(0);
  private int _currentStudentRecordIndex = 0;
}

如果您先加载或按,请确保将值重置为零。

private void LoadStudentRecords()
{
  _currentStudentRecordIndex = 0;      
  _studentRecords = new List<StudentRecord>();
  // ....

标准的第一个/上一个/下一个/最后一个逻辑:
(可以做不同的事情,只是做一些 Labda/Linq Fun 为例)。

private void btnFirst_Click(object sender, EventArgs e)
{
  var firstStudent = _studentRecords.FirstOrDefault();

  ShowStudent(firstStudent);
}

private void btnLast_Click(object sender, EventArgs e)
{
  var count = _studentRecords.Count;
  if (count > 0)
  {
    var studentRecord = _studentRecords.ElementAt(count-1);

    ShowStudent(studentRecord );
  }      
}

private void btnPrevious_Click(object sender, EventArgs e)
{
  var studentRecordIndex = _currentStudentRecordIndex - 1;

  if (studentRecordIndex > -1)
  {
    var studentRecord = _studentRecords.ElementAt(studentRecordIndex );

    ShowStudent(studentRecord );
  }      
}

private void btnNext_Click(object sender, EventArgs e)
{
  // Should be able to do this based on previous logic
}

备注

这远非完美,但我希望它能解释你在寻找什么。

【讨论】:

    【解决方案3】:

    我可能正在为你做一个任务,大声笑,但这会让你得到你想要的结果:

    class Program
    {
        // Contains the elements of an line after it's been parsed.
        static string[] array;
    
        static void Main(string[] args)
        {
            // Read the lines of a file into a list of strings. Iterate through each
            // line and create an array of elements by parsing (splitting) the line by a delimiter (eg. a comma).
            // Then display what's now contained within the array of strings.
            var lines = ReadFile("dummy.txt");
            foreach (string line in lines)
            {
                array = CreateArray(line);
                Display();
            }
    
            // Prevent the console window from closing.
            Console.ReadLine();
        }
    
        // Reads a file and returns an array of strings.
        static List<string> ReadFile(string fileName)
        {
            var lines = new List<string>();
            using (var file = new StreamReader(fileName))
            {
                string line = string.Empty;
                while ((line = file.ReadLine()) != null)
                {
                    lines.Add(line);
                }
            }
    
            return lines;
        }
    
        // Create an array of string elements from a comma delimited string.
        static string[] CreateArray(string line)
        {
            return line.Split(',');
        }
    
        // Display the results to the console window for demonstration.
        static void Display()
        {
            foreach (string item in array)
            {
                Console.WriteLine(item);
            }
    
            Console.WriteLine();
        }
    }
    

    文本文件中包含的示例如下:

    Bloggs,Joe,John,2015/01/04,M
    Jones,Janet,Gillian,2015/01/04,F
    Jenfrey,Jill,April,2015/01/04,F
    Drogger,Jeff,Jimmy,2015/01/04,M
    

    结果是:

    Bloggs
    Joe
    John
    2015/01/04
    M
    
    Jones
    Janet
    Gillian
    2015/01/04
    F
    
    Jenfrey
    Jill
    April
    2015/01/04
    F
    
    Drogger
    Jeff
    Jimmy
    2015/01/04
    M
    

    或者,根据您的业务需求,您可以使用以下解决方案生成学生记录对象列表:

    class Program
    {
        static int _recordIndex;
        static List<StudentRecord> _studentRecords;
    
        static void Main(string[] args)
        {
            // Initialize a list of student records and set the record index to the index of the first record.
            _studentRecords = new List<StudentRecord>();
            _recordIndex = 0;
    
            // Read the lines of a file into a list of strings. Iterate through each
            // line and create a list of student records of elements by parsing (splitting) the line by a delimiter (eg. a comma).
            // Then display what's now contained within the list of records.
            var lines = ReadFile("dummy.txt");
            foreach (string line in lines)
            {
                _studentRecords.Add(CreateStudentResult(line)); 
            }
    
            Display();
    
            // Prevent the console window from closing.
            Console.ReadLine();
        }
    
        // Reads a file and returns an array of strings.
        static List<string> ReadFile(string fileName)
        {
            var lines = new List<string>();
            using (var file = new StreamReader(fileName))
            {
                string line = string.Empty;
                while ((line = file.ReadLine()) != null)
                {
                    lines.Add(line);
                }
            }
    
            return lines;
        }
    
        // Get the next student record in the list of records
        static StudentRecord GetNext()
        {
            // Check to see if there are any records, if not... don't bother running the rest of the method.
            if (_studentRecords.Count == 0)
                return null;
    
            // If we are on the index of the last record in the list, set the record index back to the first record. 
            if (_recordIndex == _studentRecords.Count - 1)
            {
                _recordIndex = 0;
            }
            // Otherwise, simply increment the record index by 1.
            else
            {
                _recordIndex++;
            }
    
            // Return the record at the the new index.
            return _studentRecords[_recordIndex];
        }
    
        static StudentRecord GetPrevious()
        {
            // Check to see if there are any records, if not... don't bother running the rest of the method.
            if (_studentRecords.Count == 0)
                return null;
    
            // If we are on the index of the first record in the list, set the record index to the last record. 
            if (_recordIndex == 0)
            {
                _recordIndex = _studentRecords.Count - 1;
            }
            // Otherwise, simply deincrement the record index by 1.
            else
            {
                _recordIndex--;
            }
    
            // Return the record at the the new index.
            return _studentRecords[_recordIndex];
        }
    
        // Create a StudentResult object containing the string elements from a comma delimited string.
        static StudentRecord CreateStudentResult(string line)
        {
            var parts = line.Split(',');
            return new StudentRecord(parts[0], parts[1], parts[2], parts[3], parts[4]);
        }
    
        // Display the results to the console window for demonstration.
        static void Display()
        {
            // Display a list of all the records
            Console.WriteLine("Student records:\n----------------");
            foreach (var record in _studentRecords)
            {
                Console.WriteLine(record.ToString());
                Console.WriteLine();
            }
    
            // Display the first record in the list
            Console.WriteLine("First record is:\n----------------");
            Console.WriteLine(_studentRecords.First().ToString());
            Console.WriteLine();
    
            // Display the last record in the list.
            Console.WriteLine("Last record is:\n----------------");
            Console.WriteLine(_studentRecords.Last().ToString());
            Console.WriteLine();
    
            // Display the next record in the list
            Console.WriteLine("Next record is:\n----------------");
            Console.WriteLine(GetNext().ToString());
            Console.WriteLine();
    
            // Display the last record in the list.
            Console.WriteLine("Previous record is:\n----------------");
            Console.WriteLine(GetPrevious().ToString());
            Console.WriteLine();
        }
    
        // A record object used to store the elements of parsed string.  
        public class StudentRecord
        {
            public string LastName { get; set; }
    
            public string FirstName { get; set; }
    
            public string MiddleName { get; set; }
    
            public string Date { get; set; }
    
            public string Gender { get; set; }
    
            // Default constructor
            public StudentRecord()
            {
            }
    
            // Overloaded constructor that accepts the parts of a parsed or split string.
            public StudentRecord(string lastName, string firstName, string middleName, string date, string gender)
            {
                this.LastName = lastName;
                this.FirstName = firstName;
                this.MiddleName = middleName;
                this.Date = date;
                this.Gender = gender;
            }
    
            // Overrided ToString method which returns a string of property values.
            public override string ToString()
            {
                return string.Format(
                    "Last name: {0}\nFirst name: {1}\nMiddle name: {2}\nDate {3}\nGender: {4}",
                    this.LastName, this.FirstName, this.MiddleName, this.Date, this.Gender);
            }
        }
    }
    

    上述代码的结果如下:

    Student records:
    ----------------
    Last name: Bloggs
    First name: Joe
    Middle name: John
    Date 2015/01/04
    Gender: M
    
    Last name: Jones
    First name: Janet
    Middle name: Gillian
    Date 2015/01/04
    Gender: F
    
    Last name: Jenfrey
    First name: Jill
    Middle name: April
    Date 2015/01/04
    Gender: F
    
    Last name: Drogger
    First name: Jeff
    Middle name: Jimmy
    Date 2015/01/04
    Gender: M
    
    First record is:
    ----------------
    Last name: Bloggs
    First name: Joe
    Middle name: John
    Date 2015/01/04
    Gender: M
    
    Last record is:
    ----------------
    Last name: Drogger
    First name: Jeff
    Middle name: Jimmy
    Date 2015/01/04
    Gender: M
    
    Next record is:
    ----------------
    Last name: Jones
    First name: Janet
    Middle name: Gillian
    Date 2015/01/04
    Gender: F
    
    Previous record is:
    ----------------
    Last name: Bloggs
    First name: Joe
    Middle name: John
    Date 2015/01/04
    Gender: M
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      相关资源
      最近更新 更多