Reputation: 1
Hey everyone I was hoping you could help me with my little problem. I want to split an already split string but I get the error: "The index was outside the bounds of the array".
I know that my array is too small but I don't know how to increase that in this instance. Here is the code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Reserveringssysteem
{
public partial class Form2 : Form
{
public string naam;
public string adres;
public string datum;
public int kamernr;
public int id;
public int indexnr;
public int indexnrb;
public int indexnrc;
Kamer[] reserveringArray = new Kamer[6];
public Form2()
{
InitializeComponent();
}
private void backbtn_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form2_Load(object sender, EventArgs e)
{
using (StreamReader sr = new StreamReader(@"C:\Users\Gebruiker\Desktop\OIS\Hotelsysteem\Reserveringen.txt", Encoding.Default))
{
string text = sr.ReadToEnd();
string[] lines = text.Split(';');
foreach (string s in lines)
{
id = Convert.ToInt32(s.Split(':')[0]);
indexnr = s.IndexOf(':');
naam = s.Split('/')[indexnr];
indexnra = s.IndexOf("/");
adres = s.Split('<')[indexnra];
indexnrb = s.IndexOf('<');
kamernr = Convert.ToInt32(s.Split('>')[indexnrb]);
indexnrc = s.IndexOf('>');
datum = s.Split(';')[indexnrc];
ListViewItem opbouwera = new ListViewItem(Convert.ToString(id));
opbouwera.SubItems.Add(naam);
opbouwera.SubItems.Add(adres);
opbouwera.SubItems.Add(Convert.ToString(kamernr));
opbouwera.SubItems.Add(datum);
reserveringlistview.Items.Add(opbouwera);
}
}
}
}
}
The problem occurs from the moment I start using indexnra
. I hope one of you guys can help me out here.
Upvotes: 0
Views: 104
Reputation: 236228
I would go with regular expression to parse data from your lines. Because it describes layout of input string instead of working with substrings and indexes of some separators. Also I would use custom object which would store person data in nicely named fields:
public class Person
{
public int Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Appartment {get;set;}
public DateTime Date {get;set;}
}
And here is regular expression which defines groups for each part of data in input string:
(?<id>\d+)
first group is id - sequence of digits:
then goes separator with some spaces(?<name>[\w\s]+)
name which consists of letters and spaces/
second separator(?<address>[\w\d\s]+)
address - letters, digits, spaces<\s*(?<app>\d+)\s*>
appartment number - digits in angular brackets\s+
some spaces(?<date>\d{4}-\d{2}-\d{2})
date in yyyy-dd-MM formatUsage:
var regex = new Regex(@"(?<id>\d+):(?<name>[\w\s]+)/(?<address>[\w\d\s]+)<\s*(?<app>\d+)\s*>\s*(?<date>\d{4}-\d{2}-\d{2})");
var people = from line in lines
let match = regex.Match(line)
where match.Success
select new Person {
Id = Int32.Parse(match.Groups["id"].Value),
Name = match.Groups["name"].Value.Trim(),
Address = match.Groups["address"].Value.Trim(),
Appartment = match.Groups["app"].Value,
Date = DateTime.ParseExact(match.Groups["date"].Value.Trim(),"yyyy-dd-MM",null)
};
For this sample file
1: Jeroen Wasser Poppy Paashaas/ Bijloopstraat 21< 5> 2017-31-12;2: Bob White/ Bijloopstraat 22< 15> 2016-28-10;
You will have two people parsed:
[
{
"Id": 1,
"Name": "Jeroen Wasser Poppy Paashaas",
"Address": "Bijloopstraat 21",
"Appartment": "5",
"Date": "2017-12-31T00:00:00"
},
{
"Id": 2,
"Name": "Bob White",
"Address": "Bijloopstraat 22",
"Appartment": "15",
"Date": "2016-10-28T00:00:00"
}
]
Then grab collection of people and display them in ListView. I.e. separate data access (reading file and parsing people) with presentation (displaying data on UI).
NOTE: You can also use unnamed groups in regex. It will be less readable, but more compact:
(\d+):([\w\s]+)/([\w\d\s]+)<\s*(\d+)\s*>\s*(\d{4}-\d{2}-\d{2})
And you will have to read groups by index instead of name
Id = Int32.Parse(match.Groups[1].Value),
Upvotes: 2
Reputation: 152556
These lines are an example of the problem:
indexnr = s.IndexOf(':');
naam = s.Split('/')[indexnr];
IndexOf
will return the position within the string of the :
character (e.g. 9
if the colon is the 10th character since the index is zero-based).
s.Split('/')
will return an array of strings, so in that example you would be asking for the 10th string if you used a value of 9 for indexnr
.
All that to say that the output of IndexOf
is very likely not the appropriate index to use to find a particular string after calling Split
.
It's not clear from your code what your expected output is - if you add an example input and the expected output you can probable get a better method for getting what you need.
Upvotes: 2