views:

149

answers:

8

Hi,

I have strings with space seperated values and I would like to pick up from a certain index to another and save it in a variable. The strings are as follows:

  John Doe        Villa Grazia           323334I

I managed to store the id card (3rd column) by using:

if (line.length > 39)
{
   idCard = line.Substring(39, 46);
}

However, if I store the name and address (1st and 2nd columns) with Substring there will be empty spaces since they are not of the same length (unlike the id cards). How can I store these 2 values and removing the unneccasry spaces BUT allowing the spaces between name and surname?

Many thanks in advance.

Regards, Chris

+3  A: 
var values = line.Split(' ');
string name = values[0] + " " + values[1];
string idCard = values[4];

It will be impossible to do without database lookups on names if there aren't spaces for sure in the previous columns.

Yuriy Faktorovich
This is good general solution, but if your last name has a space in it "Mc Grath", for example, it won't work.
TheSean
You could filter the input on spaces, but this seems like a bad solution in general, csv would be at least a little better.
Yuriy Faktorovich
+1  A: 

How can you even get the ID like that, when everything in front of it is of variable length? If that was used for my name, "David Hedlund 323334I", the ID would start at pos 14, not 39.

Try this more dynamic approach:

var name = str.Substring(0, str.LastIndexOf(" "));
var id = str.Substring(str.LastIndexOf(" ")+1);
David Hedlund
No because in the text file the everything is placed under each other and at the exact position. I just tried it and it worked. All Ids were retrieved
Chris
alright, by the time i answered the question the input string was formatted to look as though there was only one space between every word, but yes, if they're all at fixed length positions with space padding in between, then murph's solution with trim() is the way to go
David Hedlund
+4  A: 

Try this:

string line    = "  John Doe        Villa Grazia           323334I";
string name    = line.Substring(02, 16).Trim();
string address = line.Substring(18, 23).Trim();
string id      = line.Substring(41, 07).Trim();
Rubens Farias
Assuming the width of each field is defined in advance (the index numbers) this is a good solution. Although, in production would be nice to pull out the numbers to constants and use them when you create the string too, so you don't introduce bugs when you change them.
TheSean
When you save them back you can use PadRight to ensure they all go back with the right amount of padding which I think is what you are after? http://msdn.microsoft.com/en-us/library/system.string.padright(VS.71).aspx
Pete Duncanson
Ideally in production you'd use some form of definition table rather than just constants - OK that's still contsants (-: just abstracted a bit.
Murph
+1  A: 

Looks like your parsing strategy will cause you a lot of trouble. You shouldn't count on the string's size in order to parse it.

Why not save the data in CSV format (John Doe, Villa Grazia, 323334I)? that way, you can assume that each "column" will be separated by a comma which will make your parsing efforts easier.

Moshe Levi
I removed the .length part. I am now using only the substring. It shoudn't cause trouble like this should it?
Chris
@Chris: Same advice on using positions inside the string, it will make your parsing code very fragile. you should try to avoid doing that.If you cannot change the format of the files and you're sure that each "column" will be in a specific fixed length that would never change (as far as you can see) than I guess this is your only option.
Moshe Levi
+1  A: 

Possible "DOH!" question but are you sure they are spaces and not Tabs? Looks like it "could" be a tab seperated file?

Also for browie points you should use String.Empty instead of ' ' for comparisons, its more localisation and memory friendly apparently.

Pete Duncanson
No they weren't tabs. If you move the cursor to the left or right, only one space is moved and not a tab.
Chris
+2  A: 

Are these actually space separated or are they really fix width columns?

By that I mean do the "columns" start at the same index into the string in each case - from the way you're describing the data is sounds like the later i.e. the ID column is always column 39 for 7 characters.

In which case you need to a) pull the columns using the appropriate substring calls as you're already doing and then, use "string ".Trim() to cut off the spaces.

If the rows, are, as it seems fixed with then you don't want to use Split at all.

Murph
They start at the same index. I implemented it by splitting the address and so on with some extra spaces at the end and then trimming the end to remove the white spaces.Thank you all :)
Chris
Not a problem - please accept @Rubens answer if its right!
Murph
A: 

The first approach would be - as already mentioned - a CSV-like structure with a defined token as the field separator.

The second one would be fixed field lengths so you know the first column goes from char 1 to char 20, the second column from char 21 to char 30, and so on. There is nothing bad about this concept besides that the human readability may be poor if the columns are filled up to their maximum so no spaces remain between them.

You could write a helper function or class which knows about the field lengths and provides an index-based, fault-tolerant access to the particular column. This function would extract the particular string parts and remove the leading and trailing spaces but leave the spaces in between as they are.

AverageCoder
They all start at the same index in the text file. My only problem that remained was that the name and address are obviously not of the same length. I fixed this by setting the substring of the name with the length of 40 (since there will be about 300 more spaces to the address) so it won't cause a problem. Then I trimmed the end to remove the white spaces
Chris
A: 

If your values have fixed width, best not split it but use the right indexes in your array.

const string input = "John Doe        Villa Grazia           323334I";
var name = input.Substring(0, 15).TrimEnd();
var place = input.Substring(16, 38).TrimEnd();
var cardId = input.Substring(39).TrimEnd();

Assuming your values cannot contain two sequential spaces in them we can maybe use " " (double space" as a separator?
The following code will split your string based on the double space

const string input = "John Doe        Villa Grazia           323334I";
var entries = input.Split(new[]{"  "}, StringSplitOptions.RemoveEmptyEntries)
                .Select(s=>s.Trim()).ToArray();
string name = entries[0];
string place = entries[1];
string idCard = entries[2];
borisCallens
If neither of these assumptions are true, you're bound to be in a world of pain
borisCallens
That is how I did. By the way... Thank you all. OMG this site is amazing! Huuuge support!! Shame I cannot vote for you guys because I am not a level 15 in reputation...
Chris
hehe, this site IS amazing. Welcome to the club ;)
borisCallens