1

Basically I'm reading in 50 lines from a text file which has a format somewhat like this for each line:

David Chalmers 34

I've read the text file using ReadAllLines so each line should be a different entry in the array.

I'm trying to take the number from each line and store them into an array of their own. Right now I'm getting the error:

Index and length must refer to a location within the string.

static void getResults(string[] Text)
{
    // X = lastIndexOf for ' ' (space)
    // x will take position of the last space
    // Results = substring
    // z will be the length of the string
    // z = text.Length
    //  Substring (x+1,z-x+1)

    int lines = 50;
    string[] Results = new string[lines];
    for (int i = 0; i < Text.Length; i++)
    {
        int x = Text[i].LastIndexOf(' ');
        int z = Text[i].Length;

        Results[lines] = Text[i].Substring(x + 1, z - x + 1);
    }
}

Any help would be appreciated!

5
  • Did you use the debugger and check your variables when you get this error? Commented Dec 17, 2015 at 15:23
  • 1
    Results[50] will be off the array - presumably you want Results[i] Commented Dec 17, 2015 at 15:25
  • 2
    Do you realize that you are writing always at the same position in the array (lines=50)? And that position doesn't exist because arrays in NET start at zero and ends at length - 1 (max 49 here)? Commented Dec 17, 2015 at 15:25
  • 1
    Shouldn't that be z - (x + 1) or z - x - 1 Commented Dec 17, 2015 at 15:25
  • I am not sure why you don't use the string.Split() method to do this it would be more efficient and less code also what if you get more than 50 lines.. at least the Split function would still work as long as the file format remains the same.. Commented Dec 17, 2015 at 15:28

8 Answers 8

4

Use Split, it's a lot easier:

String Test = "David Chalmers 34";

String[] Segments = Test.Split(' ');

Console.WriteLine(Segments[2]);

Console.ReadKey();

Of course, you'll want to add error handling for bad input.

Sign up to request clarification or add additional context in comments.

Comments

1

You must subtract 1 from the substring length instead of adding it:

var line = "David Chalmers 34";
var lineLength = line.Length; // == 17
var lastSpacePosition = line.LastIndexOf(' '); // == 14
var age = line.Substring(lastSpacePosition + 1, lineLength - lastSpacePosition - 1); // == 34

Comments

1

Your expression should be:

Results[lines] = Text[i].Substring(x + 1, z - x - 1);

You need to substract 1 instead of adding.

Comments

0

You can also do all of this in one line of Linq:

var Results = Text.Take(50)
    .Select(line => line.Split(' '))
    .Select(sa => sa.Last())
    .ToArray();

Comments

0

Here's what I would do, making use of a Person class. It may not seem necessary right now given the scope of your project, but if the scope ever grows, using classes and instances will pay off. Plus, this way, you have the names to match the ages you're seeking which is probably going to be necessary at some point anyway.

public static List<Person> GetResults(string[] text)
{
    var results = new List<Person>();

    foreach(var line in text)
    {
        results.Add(Person.Parse(line));
    }

    return results;
}

public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public static Person Parse(string fromInputLine)
    {
        ValidateInput(fromInputLine);
        var delimPosition = fromInputLine.LastIndexOf(' ');
        var name = fromInputLine.Substring(0, delimPosition);
        var age = Convert.ToInt32(fromInputLine.Substring(delimPosition + 1));
        return new Person(name, age);
    }

    private static void ValidateInput(string toValidate)
    {
        if (!System.Text.RegularExpressions.Regex.IsMatch(toValidate, @"^.+\s+\d+$")) 
            throw new ArgumentException(string.Format(@"The provided input ""{0}"" is not valid.", toValidate));
    }
}

Comments

0

You can use the method .Split from string class, what he does is to separate the string by the blank spaces, then you get an array of strings...

var entry = "David Chambers 34";
string[] result = entry.Split(" ")

then you can convert to integer

var age = Convert.ToInt32(result[2]);

or

var age = Int32.TryParse(result[2]);

Comments

0

To store the numbers in an array of their own, you could try:

string[] numbers = text.Select(x => x.Substring(x.LastIndexOf(' '))).ToArray();

Comments

-1

Use a StringReader

        static void getResults(string Text)
        {

            // X = lastIndexOf for ' ' (space)
            // x will take position of the last space
            // Results = substring
            // z will be the length of the string
            // z = text.Length
            //  Substring (x+1,z-x+1)

            StringReader reader = new StringReader(Text);

            List<string> Results = new List<string>();
            string inputLine = "";
            while ((inputLine = reader.ReadLine()) != null)
            {
                Results.Add(inputLine.Trim());
            }
        }
​

4 Comments

This doesn't do what OP is asking for (getting only the number).
Yes it does : "the number from each line and store them into an array of their own". The person didn't say to parse the number to a integer.
You're returning the whole line, not only the number part as asked: Results.Add(inputLine.Trim()); (and your method parameter is wrong too, should be string[] not string).
I think the string[] is wrong. Getting an array would convert to an array of characters and not an array of strings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.