Search code examples
c#filetextnullreferenceexceptionformatexception

Read text file into object


After hours of struggle, I need to read text file into Object. I need to skip the first 15 lines in my file but I keep getting Format Exception. Please help me. I still have a lot to learn.

Exception is => System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) at System.Convert.ToInt32(String value) at PostTicketProject.TicketHelper.LoadData(Ticket[][]& ticket, String[] fileLines) in D:\CleanTicket\PostTicketProject\PostTicketProject\Ticket.cs:line 139

public void LoadData(ref Ticket[][] ticket, string[] fileLines)
    {                            
        try
        {

            //split each line into many columns using single white space, ignore tabs and double white space

                var data = fileLines[i].Replace("  ", string.Empty).Replace("\t", string.Empty).Split(' ');

                for (int i = 15; i< fileLines.Length; i++)
            {
                //split each line into many columns using single white space, ignore tabs and double white space

                var data = fileLines[i].Replace("  ", string.Empty).Replace("\t", string.Empty).Split(' ');

                for (int j = 0; j < fileLines[i].Length; j++)
                {
                    ticket[i][j] = new Ticket //this line throws format exception
                    {
                        ErrCode = Convert.ToInt32(data[j]),
                        DefectName = data[j],
                        Action = Convert.ToInt32(data[j]),
                        JudeTime = data[j],
                        UserName = data[j],
                    };
                }
            }                  
        }
        catch (FormatException FEx)
        {
            Console.WriteLine("Exception is => {0}", FEx);
        }
        catch (NullReferenceException NRefEx)
        {
            Console.WriteLine("Exception is => {0}", NRefEx);
        }
    }

line that read text file can read and print out the content. Seems no issue here

try
        {
            fileLines = File.ReadAllLines(@"D:\postTicket\repairTicket_post.txt");
        }
        catch (IOException IOEx)
        {
            Console.WriteLine("Failed to load file... Exception is => {0}", IOEx);
        }

my file structure is below

pin start date time = 2019-03-14-01-45-05

pin end date time = 2019-03-15-02-47-05

ups star date skip = 19

operator name = ups

. . .

star number = 12

0 [#]pass 0 2019-03-15-02-47-05 userName

0 [#]pass 0 2019-03-15-02-47-05 userName

0 [#]pass 0 2019-03-15-02-47-05 userName

400000 [#]Missing[@]image 1 2019-03-15-02-40-05 userName

8000 [#]Offset[@]image 1 2019-03-15-02-46-10 userName

0 [#]pass 0 2019-03-15-02-47-05 userName

Thanks for all your help


Solution

  • I found a few mistakes in your code. I'll go threw it and explain what I find odd.

    for (int i = 0; i< fileLines.Length; i++)
    {
        while (i > 14)
        {
    

    I think you intended to write if (i > 14) because now as soon as you reach line 15 you will be stuck in an endless loop. As an alternative to the if you could just initialize i with 14.

    var data = fileLines[i].Replace("  ", string.Empty).Replace("\t", string.Empty).Split(' ');
    

    I'm guessing you just want to remove spaces and tabs at the beginning and/or the end of the line. In that case you could use Trim()/TrimStart()/TrimEnd() but I might be mistaken in which case your Replaces are the best solution.

    for (int j = 0; j < fileLines[i].Length; j++)
    

    In this for loop you want to loop over the split strings in data, but you are using j < fileLines[i].Length as your condition. this will run the for-loop for the amount of characters in the line and not the amount of split substrings. For that to work you need iterate over the data array like this: i < data.Length.

    ticket[i][j] = new Ticket
    {                                                                                               
        ErrCode = Convert.ToInt32(data[j]),
        DefectName = data[j],
        Action = Convert.ToInt32(data[j]),
        JudeTime = data[j],
        UserName = data[j],                               
    };
    

    In this segment you are creating your Ticket. The problem is that first you didn't create the inner array which most likely caused your NullReferenceException and secondly you are always using the same substring. Which in the unlikely case that your ErrCode, DefectName, Action, JudeTime and UserName are all number and the same is correct, but that is probably not what you intend. The solution would be to use a 1-dimensional array instead of the 2-deimensional one and not iterate over the spit substrings, but instead create the object there with the data array.

    Updated code:

    public void LoadData(ref Ticket[] ticket, string[] fileLines)
    {                            
        try
        {
    
            //to read and store the text file data in the ticket object
    
            ticket = new Ticket[fileLines.Length];
    
            for (int i = 14; i < fileLines.Length; i++)
            {
                //split each line into many columns using single white space, ignore tabs and double white space
    
                var data = fileLines[i].Replace("  ", string.Empty).Replace("\t", string.Empty).Split(' ');
    
                ticket[i] = new Ticket
                {                   
                    ErrCode = Convert.ToInt32(data[0]),
                    DefectName = data[1],
                    Action = Convert.ToInt32(data[2]),
                    JudeTime = data[3],
                    UserName = data[4],
                };
            }
        }
        catch (FormatException FEx)
        {
            Console.WriteLine("Exception is => {0}", FEx);
        }
        catch (NullReferenceException NRefEx)
        {
            Console.WriteLine("Exception is => {0}", NRefEx);
        }
    }
    

    This assumes the format of the lines to be:

        <ErrCode> <DefectName> <Action> <JudeTime> <UserName>
    

    If the order is different you need to adjust the indexes into the data array.