Hi all... My first post in this forum... The problem is that of the String.Split method... I cant seem to get the String.Split method to work as I wanted... My objective is to try to read the data which are three columns of numbers and try to array them so that I can use them as points for contour plotting. The following is the data displayed in the file I tried to read from.

20311 20316 20321
20312 20317 20322
20313 20318 20323
20314 20319 20324
20315 20320 20325

My method is as follow:

while(objInput.Peek()>-1)
{
string strLine = objInput.ReadLine();
string [] split = strLine.Split(new Char [] {' '});
}

After which I can then initialise the split[0], split[1], split[2] etc to whatever arraylist i am going to use. However, these values are displayed as null value (blank) when I tried to console.writeline them.

The strange thing is when I edited the .dat file which I used to read the strings, and placed a comma instead of just spaces in between the words as illustrated below, the split method worked out fine when I used the following code in place of the above code.

20311 ,20316 ,20321
20312 ,20317 ,20322
20313 ,20318 ,20323
20314 ,20319 ,20324
20315 ,20320 ,20325

while(objInput.Peek()>-1)
{
string strLine = objInput.ReadLine();
string [] split = strLine.Split(new Char [] {','});
}

Can anyone help me with this problem? Did I use the String.Split method wrongly? Or what did I not do?

Dani AI

Generated

Nice catch on the leading padding, . Empty entries from those spaces are what tripped up your first attempt. You do not need regex if you simply want to treat any run of whitespace (spaces, tabs) as a delimiter and ignore blanks. Split on default whitespace and drop empties, then build a 2D array. Streaming lines also avoids loading the whole file, unlike ReadToEnd.

using System;
using System.Collections.Generic;
using System.IO;

var rows = new List<int[]>();
foreach (var line in File.ReadLines("values.dat"))
{
    // null separator => split on all whitespace; RemoveEmptyEntries skips leading padding
    var parts = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
    if (parts.Length == 0) continue; // skip blank lines
    rows.Add(Array.ConvertAll(parts, int.Parse));
}

// validate rectangular shape
int cols = rows[0].Length;
for (int i = 1; i < rows.Count; i++)
    if (rows[i].Length != cols)
        throw new FormatException("Inconsistent column count.");

var grid = new int[rows.Count, cols];
for (int r = 0; r < rows.Count; r++)
    for (int c = 0; c < cols; c++)
        grid[r, c] = rows[r][c];

This gives you a clean int[,] for contour plotting. If your data are doubles, use double.Parse(..., CultureInfo.InvariantCulture).

Building on ’s regex tip: , if you want to keep the whitespace tokens themselves (e.g., alternate between words and the exact spaces), use a capturing group. Captured delimiters are returned in the result:

using System.Text.RegularExpressions;

var tokens = Regex.Split(line, "(\\s+)");

Now tokens contains words and the whitespace between them. If you want only literal spaces (not tabs), use ([ ]+) instead of (\s+).

Recommended Answers

All 9 Replies

Hi, i tried out your code and it seems to work even with the spaces, however one remark: i don't know if it was your intention to initialize the split variable inside the loop...so keep in mind that it will be overwritten all the time and just keeps the latest 3 values (from the last readline)

hrm... I understand where the error comes from already. It comes from the spaces before the numbers... which I never put in my question. The actual display is as shown below:

(spaces) 20311 20316 20321
(spaces) 20312 20317 20322
(spaces) 20313 20318 20323
(spaces) 20314 20319 20324
(spaces) 20315 20320 20325

and not the following:

20311 20316 20321
20312 20317 20322
20313 20318 20323
20314 20319 20324
20315 20320 20325

So, how do I solve this kind of problem?

StreamReader objInput = new StreamReader("C:\\values.dat", System.Text.Encoding.Default);
string contents = objInput.ReadToEnd().Trim();
string [] split = System.Text.RegularExpressions.Regex.Split(contents, "\\s+", RegexOptions.None);			
foreach (string s in split)
{
	Console.WriteLine(s);
}

Wow... Thanks alot, rOckbaer! It worked perfectly! I will now try to read them into an array. Any idea how it can be done? Its of two dimensional array, right?

string [] split = System.Text.RegularExpressions.Regex.Split(contents, "\\s+", RegexOptions.None);

split is already a string array

Thanks again! May I know what the \\s+ means? Cant seem to find it on the web.

\s+ is a regular expression, the \s means to consider whitespaces and the + means to consider at least 1 occurence or more of them

Ah.... IcIc... Thats exactly what I need! No wonder it worked perfectly!

Thanks alot!

StreamReader objInput = new StreamReader("C:\\values.dat", System.Text.Encoding.Default);
string contents = objInput.ReadToEnd().Trim();
string [] split = System.Text.RegularExpressions.Regex.Split(contents, "\\s+", RegexOptions.None);			
foreach (string s in split)
{
	Console.WriteLine(s);
}

Hi _r0ckbaer,

I don't know if you are still around...

What do I need to modify in the "System.Text.RegularExpressions.Regex.Split(contents, "\\s+", RegexOptions.None);" so the string will also expect whitespaces?

For example, in the .dat file you have:

Hello Word Test1 Test2 Test3

If you noticed, I have whitespaces between each words, I want to keep that.

so

string[0] = Hello
string[1] = " "
string[2] = Word
string[3] = " "
string[4] = Test1
string[5] = " "

..
..... and so on. Can this be done using the same Regex?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.