Reputation: 43
I've been trying to do this for about 6 hours now and i'm stumped..
I want the equivalent of this in C#:
$settings = array();
foreach(file('settings.txt') as $l) $settings[]=explode(',',$l);
print $settings[0][2];
This is what i've got so far that doesn't work:
string fileName = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\" + "settings.txt";
string[,] settings;
FileStream file = null;
StreamReader sr = null;
try
{
file = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Read);
sr = new StreamReader(file, Encoding.ASCII);
string[] line;
int i = 0;
do
{
line = sr.ReadLine().Split(',');
settings[i++, 0] = line[0];
} while (line != null);
file.Close();
MessageBox.Show(settings[1, 0]);
} catch (Exception err) { MessageBox.Show(err.Message); }
I get "Object reference not set to an instance of an object", any ideas would be greatly appreciated..
Upvotes: 4
Views: 1793
Reputation: 22433
There was a code-golf question about a similar problem last week. And by request I wrote a version that used LINQ. You can check it out on my site.
You probably want to adapt it a bit for your needs...
static void Main(string[] args)
{
string[][] lines = null;
using (var lp = "settings.txt".Load())
lines = lp.Select(l => l.Split(',')).ToArray();
}
http://hackersbasement.com/?p=96 (and just in case my site ever changes)
public static class LineProcessorLinq
{
public static LineProcessor Load(this string fileName)
{
return new LineProcessor(fileName);
}
public static void Write(this IEnumerable<string> lines, string header, string footer, string fileName)
{
using (var fs = File.AppendText(fileName))
lines.Write(header, footer, fs);
}
public static void Write(this IEnumerable<string> lines, string header, string footer, StreamWriter writer)
{
if (writer == null)
throw new ArgumentNullException("writer");
if (!string.IsNullOrEmpty(header))
writer.Write(header);
foreach (var line in lines)
writer.Write(line);
if (!string.IsNullOrEmpty(footer))
writer.Write(footer);
}
}
public class LineProcessor : Component, IEnumerable<string>
{
private StreamReader _reader = null;
public LineProcessor(string fileName) : this(File.OpenText(fileName)) { }
public LineProcessor(StreamReader reader)
{
if (reader == null)
throw new ArgumentNullException("reader");
_reader = reader;
}
protected override void Dispose(bool disposing)
{
if (disposing && _reader != null)
_reader.Close();
}
#region IEnumerable<string> Members
public IEnumerator<string> GetEnumerator()
{
var currentPos = _reader.BaseStream.Position;
while (!_reader.EndOfStream)
yield return _reader.ReadLine();
if (_reader.BaseStream.CanSeek)
_reader.BaseStream.Seek(currentPos, SeekOrigin.Begin);
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
#endregion
}
Upvotes: 0
Reputation: 43
Thanks for the super fast answers!!
I settled on:
List settings = new List();
foreach (string line in File.ReadAllLines("settings.txt", System.Text.Encoding.ASCII)) settings.Add(line.Split(','));
Thanks!
Dean.
Upvotes: 0
Reputation: 545518
Use a jagged array instead of a multidimensional one – or better yet, a List<string[]>
:
var settings = new List<string[]>();
foreach (string line in File.ReadLines("settings.txt", System.Text.Encoding.ASCII))
settings.Add(line.Split(','));
Marc's use of LINQ instead of the loop is a good alternative.
Upvotes: 7
Reputation: 1499860
Well, that shouldn't even compile - you never initialize the value of settings
. Arrays in .NET are of a fixed size - it looks to me like you should be using a List<string[]>
instead:
List<string> settings = new List<string>();
using (TextReader reader = File.OpenText(fileName, Encoding.ASCII))
{
string line;
while ((line = reader.ReadLine()) != null)
{
settings.Add(line.Split(','));
}
}
MessageBox.Show(settings[1][0]); // Shows the first part of the second line
(Note that this also makes sure that the file gets closed even if exceptions occur - you should definitely learn about the using
statement. Marc's solution avoids this by loading all the lines in a single call, which obviously has a memory overhead but is otherwise good.)
Upvotes: 3
Reputation: 1062550
If you are going to look at lots of different cells:
string[][] lines = File.ReadAllLines(path).Select(
line => line.Split(',').ToArray()).ToArray();
Console.WriteLine(lines[0][2]);
If you only want [0][2], you can limit it a bit...
using (StreamReader sr = File.OpenText(path))
{ // only read the first line (zero)
Console.WriteLine(sr.ReadLine().Split(',')[2]);
}
Upvotes: 3
Reputation: 48088
You should initiate your array first, like that :
string[,] settings = new string[3,3];
EDIT : Also by this line, you skip to set first item of the array :
settings[i++, 0] = line[0];
You should assign your value like that :
settings[i, 0] = line[0];
i++;
Upvotes: 3