0
votes

I am stuck on a problem where I need to split a file with fixed width. Each field can be identified by its first character.

The file contains multiple format for example, the first row's format is {1, 11, 12} while second row's format is {1, 10, 12}. Both are identified with the first character.

AFirstField SecondFields
BBField    SecondFields

However, sometimes a row can come with less characters like below.

AFirstField S

What I have tried so far is using text parser getting the current line and check the first character to decide the format, but the application falls over because sometimes rows have less data on them, like the A example above.

string[] data;

    using (TextFieldParser myReader = new TextFieldParser(filePath))
    {
        myReader.TextFieldType = FieldType.FixedWidth;

        while (!myReader.EndOfData)
        {
            currentLine = myReader.ReadLine();
            recordType = currentLine[0].ToString();

            if (!recordType.Equals("H"))
            {
                myReader.FieldWidths = returnLineFormat();
                myReader.HasFieldsEnclosedInQuotes = true;
               data = myReader.ReadFields();



                //if (recordType.Equals("R"))
                //{
                //    ISD.Add(data);
                //}

            }

        }

    }


private int[] returnLineFormat()
{
    int[] format = null;

    if ((recordType == "A"))
    {
        format = new int[] { 1, 11, 12};
    }
    else if ((recordType == "B"))
    {
        format = new int[] { 1, 10, 12};
    }

    return format;
}

These are the errors I am getting cause of row having less stuff: Line 3 cannot be parsed using the current FieldWidths.

Is there a way around this problem?

1
Is there a library you can use ??? there are plenty in java - Bruce Martin
I am using C# .net. - Madasir Ahmed
you can not split the line by space character? - Chetan
you can set the last one as -1 indicating a variable width (e.g. format = new int[] { 1, 11, -1};. If there's a chance that you'll have a blank line you may want to also add a condition after the myReader.ReadLine() to check for that before calling currentLine[0] or you'll get an error. - C. Mitchell

1 Answers

0
votes

Try this. It should work

static int[] returnLineFormat(string recordType)
{
    int[] format = null;

    if ((recordType == "A"))
    {
        format = new int[] { 1, 11, 12 };
    }
    else if ((recordType == "B"))
    {
        format = new int[] { 1, 10, 12 };
    }

    return format;
}

static void Main(string[] args)
{
    string[] data;

    using (TextFieldParser myReader = new TextFieldParser(@"TextParserExample.txt"))
    {
        myReader.TextFieldType = FieldType.FixedWidth;

        while (!myReader.EndOfData)
        {
            var recordType = myReader.PeekChars(1);

            if (!recordType.Equals("H"))
            {
                var lineLength = myReader.PeekChars(1000).Length;
                var currentLine = myReader.ReadLine();
                var lengths = returnLineFormat(recordType);
                lengths[2] = lineLength - (lengths[0] + lengths[1]);

                myReader.FieldWidths = lengths;
                myReader.HasFieldsEnclosedInQuotes = true;
                data = myReader.ReadFields();
            }

        }
    }
}