1

I'm having trouble finding a nice way to parse out an object I have in C# in a fixed width format. The object has various properties. I found that the cleanest way to parse out the data itself was to use string formatting, so I need the lengths of each field. I currently have a static class set up like this:

public static class LENGTHS
{
    public static int FIRST_NAME = 15;
    public static int LAST_NAME = 25;
    public static int ADDRESS1 = 25;
    etc...
}

The lengths are then placed into an array. So like [15, 25, 25]

Then the data fields are placed into another array in the same order:

string[] info = { obj.Firstname, obj.LastName, obj.Address1, etc...};

I should also mention that every time the info string will be the exact same, and will not change overall unless I change only the order, in which case it will be changed every time.

They are then passed into a parser I made which finds the length of the field, and how long it should be from the length array, and inserts blank spaces accordingly using String.Format.

FixedWidthParser(info, Lengths);

The issue then is having to maintain the order for both of these arrays. In the event I have to change the order, I'd have to change the order of both arrays.

Am I going about this the wrong way? Is there a better way to do this? If so, can someone point me in the right direction?

ilyketurdles
  • 113
  • 1
  • 11
  • 1
    So, is your FixedWidthParser **parsing** or *writing*? Because it sounds like you're writing yet parsing is the opposite. Am confused. You ask for better ways, but you haven't told us your requirements, so I'm not sure. The best way is to serialize your objects to gotdamn xml and be done with it already. There's plenty of stuff in the framework to help you serialize objects. USE THEM. –  Jul 09 '15 at 14:45
  • @Will While I would agree with you in general there are also any number of reasons to do things this way. But this question seems to be less about how to serialize and more about alternative ways of storing related information without redundancy. I think that is an excellent goal - being aware of mutual dependency and trying to enforce the relationship more strongly. – ryachza Jul 09 '15 at 14:51
  • I'm trying to write. Sorry, I was told to 'parse', which kind of threw me off to since we are trying to write, figured I was just wrong in my definition of parse, so thanks for clearing that up. I will look into serialization. – ilyketurdles Jul 09 '15 at 14:52
  • @zjm nah, looks like serialization to me. Dropping properties into a fixed field length format. Not sure what you're seeing, or seeing through. *(sits back, sips tea, satisfied with the implication that you're high)* –  Jul 09 '15 at 15:02
  • @Will Huh? It's definitely serialization. My point was that the question was worth actually answering, rather than saying use the built in serialization options. Perhaps it was specified to be fixed width for interoperability or requirements regarding output size? The question was not "how to serialize", it seems like that part was working fine. The question was "how to I remove redundancy from my configuration". – ryachza Jul 09 '15 at 15:06
  • @ZJM Serialization with less of a chance of things getting screwed up later, yes. –  Jul 09 '15 at 15:25
  • Is there an easy way to serialize to a text file without XML tags? The file being written to is for another program, which I don't have access to, so it wouldn't be able to deserialize xml. I can get my program to work to do exatly what I want (which is, again, output certain fields from an object to a text file with fixed width columns). I'm just looking for a "proper" way to do this. – ilyketurdles Jul 09 '15 at 15:30
  • @user3499700 If I'm understanding correctly and you need to serialize objects to a specification that you can't change (don't control the deserialization), what you're doing is perfectly fine (assuming it matches what the target system expects). For an option to reduce the separation of the size and order configurations, you can see my answer. Reflection may be a bit "stronger" than what you need, but to asses that I would need to see more of what you're doing. – ryachza Jul 09 '15 at 16:02

2 Answers2

3

One possible solution would be to create a custom attribute for width and add it on the fields in the obj type. Then somewhere store the field names in an array to provide the order for serialization. You can then use reflection to look up the fields by name, look up the length attribute on that field, and serialize [theorectically] the same way you're doing so now.

To get a field by name:

Type.GetField(string, BindingFlags)

https://msdn.microsoft.com/en-us/library/4ek9c21e(v=vs.110).aspx

To get the attributes of a field:

Getting the attributes of a field using reflection in C#

Community
  • 1
  • 1
ryachza
  • 4,460
  • 18
  • 28
0

This task isn't that hard to write from scratch. But there are a number of conveniences that can be added with a bit more work.

SoftCircuits.FixedWidthParser NuGet package will easily read a fixed width file and, optionally, automatically map the fields to class properties.

It also writes fixed-width files.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466