Search code examples
c#winformstextboxstreamreaderstreamwriter

Updating line of a file if array element matches text box


I have a method which currently reads all lines of a directory file (3 fields per line) and updates a directory array with a record of text box entries if the extension code entered matches an extension code field in the file.

I had the updated directory array displaying to a list view, as soon as I attempted to update the directory file with the updated array, it all went downhill! Edit to clarify: with the latest version of the code below, the array no longer displays to the list view, and the file is not updated. No errors are thrown.

public void updateName()
    {
        int count = 0;
        string[] lines = File.ReadAllLines(directoryFile);

        // Set size of directory array equal to number of lines in file
        int lineCount = lineCounter();
        directory = new record[lineCount];

        record currentRecord = new record();

        // Iterate through each line in file
        foreach (string line in lines)
        {
            // Split current line into three fields
            string[] fields = line.Split(',');

            // Save current line as new record with surname, forename and extCode fields
            currentRecord.surname = fields[0];
            currentRecord.forename = fields[1];
            currentRecord.extCode = Convert.ToInt32(fields[2]);

            // If extension code in current record matches text box entry
            if (Convert.ToInt32(fields[2]) == Convert.ToInt32(txtExtCode.Text))
            {
                // Change surname and forname fields to match text box entries
                currentRecord.surname = txtForename.Text;
                currentRecord.forename = txtSurname.Text;

                using (StreamWriter writer = new StreamWriter(directoryFile))
                {
                    for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
                    {
                        if (currentLine == count)
                            writer.WriteLine(currentRecord);
                        else
                            writer.WriteLine(lines[currentLine - 1]);
                    }
                }
            }

            // Save currentRecord as next element in directory array, then increment
            directory[count] = currentRecord;
            count++;
        }
    }

Solution

  • You don't need a linecounter(). The number of lines is lines.Length. But why do you need this directory array? You are filling it, but you are not using it anywhere.

    Another major problem is that you are creating a StreamWriter inside the foreach loop. You should open the file before the loop and close it after the loop to make it work. Also, you are mixing writing currentRecord which is of type record and writing lines of type string to the output file. This cannot work.

    You are also putting txtForename.Text into currentRecord.surname instead of currentRecord.forename and vice versa.

    I suggest to first apply the change in the lines array and then to write this lines array back to to file with File.WriteAllLines which is the symmetric operation to File.ReadAllLines.

    I'm applying the change directly to fields array, so that I can convert it back to a string with String.Join (it is the symmetric operation to String.Split).

    public void updateName()
    {
        // Do this conversion before the loop. We need to do it only once.
        int selectedCode = Convert.ToInt32(txtExtCode.Text);
    
        string[] lines = File.ReadAllLines(directoryFile);
        for (int i = 0; i < lines.Length; i++)
        {
            // Split current line into three fields
            string[] fields = lines[i].Split(',');
    
            int extCode = Convert.ToInt32(fields[2]);
            if (extCode == selectedCode)
            {
                fields[0] = txtSurname.Text;
                fields[1] = txtForename.Text;
                lines[i] = String.Join(",", fields);
    
                // If the extension code is unique, leave the for-loop
                break;
            }
        }
        File.WriteAllLines(directoryFile, lines);
    }
    

    I also use for instead of foreach in order to have an index i, so that I can replace a single line in the lines array at a specific index.

    I don't know if the extension code in the directory file is unique. If it is, you can exit the for loop prematurely with break.