Reading from CSV file and store to an array - c#

Can you please help me with C#.
I am trying to create a function in C# that opens a CSV file and save them to an array:
FileStream fileStream = new FileStream(guid.ToString(), FileMode.Open);
for (int i = 1; i > 200; i++) // it checks the first 200 lines
{
int j = 0;
string[] str = new string[j];
do
{
// saving each character to the variable until comma is found
} while(str == '\n'); // read each character in a for loop until new line character found
}
Can you please help me out?

Something like this:
using (StreamReader r = new StreamReader(guid.ToString()))
{
string line;
int linesCount;
ArrayList result = new ArrayList();
while ((line = r.ReadLine()) != null && linesCount++ <= 200)
{
result.AddRange(line.Split(','));
}
}

Parsing CSV by hand is actually pretty tricky. You might be better off reusing the TextFieldParser (add a reference to the Microsoft.VisualBasic assembly).
using Microsoft.VisualBasic.FileIO;
....
string[,] parsedCsv;
List<string[]> csvLines = new List<string[]>();
TextFieldParser parser = new TextFieldParser(new FileStream(guid.ToString(), FileMode.Open));
parser.Delimiters = new string[] { "," };
parser.TextFieldType = FieldType.Delimited;
int maxLines = 200, lineCount = 0;
try
{
while (!parser.EndOfData && lineCount++ < maxLines)
{
csvLines.Add(parser.ReadFields());
}
}
catch (MalformedLineException)
{
Console.WriteLine("Line Number: {0} Value: {1}", parser.ErrorLineNumber, parser.ErrorLine);
return;
}
parsedCsv = new string[csvLines.Count, csvLines[0].Length];
for (int i = 0; i < csvLines.Count; i++)
{
for (int j = 0; j < csvLines[i].Length; j++)
{
parsedCsv[i, j] = csvLines[i][j];
}
}
I have assumed here that the output is going to be a 2-D array of strings - you may need to adjust this code depending on what you are after, especially if you have to cope with the situation where each line does not have the same number of fields (perhaps unlikely, but still).
The really useful thing about TextFieldParser is that it will cope with different kinds of delimeters. By setting parser.Delimiters = new string[] { "\t" };, for example, this same code could parse tab-delimited text.

What about:
string[] lines = File.ReadAllLines(path);
if(lines.Length >= 200){
for(int i = 0; i < 200; i++){
string[] str = lines[i].Split(',');
//do something here
}
}

You can just use the string.Split(',') extension method.
using (StreamReader streamReader = new StreamReader(File.OpenRead(guid.ToString())))
{
for (int i = 0; i <= 200; ++i)
{
string[] str = streamReader.ReadLine().Split(',');
}
}
The Split extension method will return a string array of the individual values separated by a comma.

Related

from text file into 2D array

I don't have idea how make functional program and I wanna transfer text file into 2D array.
Thank you for answers
This is content of my text file:
0000000011
0011100000
0000001110
1000011100
1000000000
0000111111
1000001100
1000000000
1000011000
1000001111
Code:
static void Main(string[] args)
{
int[,] map = new int[10, 10];
StreamReader reader = new StreamReader(#"Lode.txt");
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
**WHAT I SHOULD PUT HERE**
}
}
reader.Close();
}
You should do following (code with my comments):
var map = new int[10, 10];
using (var reader = new StreamReader("Lode.txt")) // using will call close automatically
{
for (var i = 0; i < 10; i++)
{
var line = reader.ReadLine(); // read one line from file
for (var j = 0; j < 10; j++)
{
map[i, j] = Int32.Parse(line[j].ToString()); // get one symbol from current line and convert it to int
}
}
}
You can try with a little LINQ as follows:
static void Main(string[] args)
{
string filePath = #"Lode.txt";
// Read file contents and store it into a local variable
string fileContents = File.ReadAllText(filePath);
/* Split by CR-LF in a windows system,
then convert it into a list of chars
and then finally do a int.Parse on them
*/
int[][] map = fileContents.Split('\r', '\n')
.Select(x => x.ToList())
.Select(x => x.Select(y => int.Parse(new string(y, 1))).ToArray())
.ToArray();
}

(jagged array) Array of an Array: automatically create in while loop, how to initialize?

I would like to create an array of an array from a text file...
There are 20000 line with 21 strings in each line separated by ',' .
I would like to read each line and make it into an array , each line being a new array within.
So I wanted to create the jagged array by starting it like this:
string[][] SqlArray = new string[200000][21];
But it gives: ERROR MESSAGE : Invalid rank specifier: expected ',' or ]
How would I create this array or initialize it?
I will be populating the data in the array like this:
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
for (int i = 0; i < workingArray.Length; i++)
{
for (int k = 0; k < 20; k++)
{
SqlArray[i][k] = workingArray[k];
}
}
}
Thank you
That type of initialization only works in Java. You must declare an array of arrays then initialize each in a loop.
string[][] SqlArray = new string[21][];
for(int index = 0; index < SqlArray.Length; index++)
{
SqlArray[index] = new string[2000000];
}
Alternatively, you can use a non-jagged array. It will probably work for what you need.
string[,] SqlArray = new string[21 , 2000000];
It can be accessed like so:
SqlArray[2,6264] = x;
To anyone who is interested this is how I ended up implementing it:
TextReader readIn = File.OpenText("..\\..\\datafile.txt");
string[][] SqlArray = new string[rowNumCreate][];
int e = 0;
while (true)
{
string theline = readIn.ReadLine();
if (theline == null) break;
string[] workingArray = theline.Split(',');
SqlArray[e] = new string[valuesInRow +1];
for (int k = 0; k < workingArray.Length; k++)
{
SqlArray[e][k] = workingArray[k];
}
e++;
}
The file being read is a simple mock database set as a flat file that was auto-generated to test an algorithm that I am implementing, which works with jagged arrays; hence instead of working with a data base I just created this for ease of use and to increase and decrease size at will.
Here is the code to build the text file:
Random skill_id;
skill_id = new Random();
// int counter =0;
string seedvalue = TicksToString();
int rowNumCreate = 200000;
int valuesInRow = 20;
string lineInFile = seedvalue;
string delimiter = ",";
for (int i = 0; i < rowNumCreate; i++)
{
for (int t = 0; t < valuesInRow; t++)
{
int skill = skill_id.Next(40);
string SCon = Convert.ToString(skill);
lineInFile += delimiter + SCon;
}
if (rowNumCreate >= i + 1)
{
dataFile.WriteLine(lineInFile);
lineInFile = "";
string userPK = TicksToString();
lineInFile += userPK;
}
}
dataFile.Close();
public static string TicksToString()
{
long ms = DateTime.Now.Second;
long ms2 = DateTime.Now.Millisecond;
Random seeds;
seeds = new Random();
int ran = seeds.GetHashCode();
return string.Format("{0:X}{1:X}{2:X}", ms, ms2, ran).ToLower();
}
I am still a student so not sure if the code is A-grade but it works :)

Value was either too large or too small for an Int32. Reading and parsing textfile

I have been unable to apply any solutions to this issue. The exception happens to this line here: currentMap[row, col] = Int32.Parse(s); What I am wanting to do is pass this method a specific file storing rows of numbers like this:
1,1,1
1,0,1
1,1,1
I then want each number to be stored in int[,] currentMap which gets returned. The file I am using contains no large numbers. I think that the size of array I am creating is right and so I don't understand why this isn't working. I am used to doing similar stuff using NextInt in java but I couldn't find any alternative for c#.
Thanks for any help.
private int[,] LoadMapArray(String filename)
{
int[,] currentMap;
int rows = 0;
int cols = 0;
StreamReader sizeReader = new StreamReader(filename);
using (var reader = File.OpenText(filename))
{
while (reader.ReadLine() != null)
{
string line = sizeReader.ReadLine();
cols = line.Length;
rows++;
}
}
currentMap = new int[rows,cols];
StreamReader sr = new StreamReader(filename);
for (int row = 0; row < rows + 1; row++)
{
string line = sr.ReadLine();
string[] split = new string[] {","};
string[] result;
result = line.Split(split, StringSplitOptions.None);
int col = 0;
foreach (string s in result)
{
currentMap[row, col] = Int32.Parse(s);
col++;
}
}
return currentMap;
}
Edit: Code was fixed after changing how I was accessing the file. I then had to change this to catch null:
for (int row = 0; row < rows + 1; row++)
{
string line = sr.ReadLine();
string[] split = new string[] { "," };
string[] result;
if (line != null)
{
result = line.Split(split, StringSplitOptions.None);
int col = 0;
foreach (string s in result)
{
currentMap[row, col] = Int32.Parse(s);
col++;
}
}
}
No, the size of your array is not correct. You read two lines at each loop but you increment the rows counter just one time.
using (var reader = File.OpenText(filename))
{
string line = string.Empty;
while ((line = reader.ReadLine()) != null)
{
rows++;
}
}
And I am sure that also the cols count is not correct, but it doesn't raise an exception because you are dimensioning the cols dimension bigger than required. (You count also the space for the commas, not just the numbers)
A simpler approach (if your file is not very big) is to use File.ReadAllLines()
string[] split = new string[] {","};
string[] lines = File.ReadAllLines(filename);
int rows = lines.Length;
int cols = lines[0].Split(split, StringSplitOptions.RemoveEmptyEntries).Count();
currentMap = new int[rows,cols];
for (int row = 0; row < rows; row++)
{
string line = lines(row);
string[] result = line.Split(split, StringSplitOptions.None);
int col = 0;
foreach (string s in result)
{
int value;
Int32.TryParse(s, out value)
currentMap[row, col] = value;
col++;
}
}
Now, the entire file is in memory with just one disk operation and you could work using the in memory strings. The parsing of the integer should be changed to use Int32.TryParse to avoid exception in case the retrieved value is not a valid integer.

Any way to process a string according to format type/ plot data from txt file?

A tab delimited txt file is being read line by line into a list of strings. the aim is to process each word of the string with the format type of the string like datetime or, float or string of characters etc.? so that the data can be plotted . Is there any other efficient way to do this?
using (StreamReader file = new StreamReader(#"C:\Users\\Desktop\snpprivatesellerlist.txt"))
{
while ((line = file.ReadLine()) != null)
{
char[] delimiters = new char[] { '\n' };
string[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < parts.Length; i++)
{
st = parts[i];
// process the line - if part[i] is date time - do something ()
// if part[i] is a float - do something else()
}
}
}
Any help and insight is appreciated.
Thanks.
I would suggest using TryParse, like so...
string line;
using (StreamReader file = new StreamReader(#"C:\Users\Desktop\snpprivatesellerlist.txt"))
{
while ((line = file.ReadLine()) != null)
{
string st;
DateTime dtPart;
float flPart;
char[] delimiters = new char[] { '\n' };
string[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < parts.Length; i++)
{
st = parts[i];
if (DateTime.TryParse(st, out dtPart))//Is of type DateTime
{
//Do something with DateTime dtPart
}
else if (float.TryParse(st, out flPart))//Is of type float
{
//Do something with float flPart
}
else//Can be considered a string
{
//Do something with string st
}
}
}
}
If the Fields that come in your tab-delimited file are of the same type always, and no.of fields are fixed.
Then you can create a class of structure to store each line value.
class LineData
{
public float a {get; set;}
public DateTime b {get; set;}
}
In the method implementation (i.e. in the while):
string[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
//You know 1st column is float, 2nd column is datetime
var dt = new LineData();
float.TryParse(parts[0], out dt.a);
DateTime.TryParse(parts[1], out dt.b);
//...
//store dt in a list/array. (not shown here)
The code that kinda solved my issue - but i am still working it.
using (StreamReader file = new StreamReader(#"C:\Users\Desktop\snpprivatesellerlist.txt"))
{
while ((line = file.ReadLine()) != null)
{
char[] delimiter1 = new char[] { '\n' };
string[] part1 = line.Split(delimiter1, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < part1.Length; i++)
{
sepList.Add(part1[i]);
//st = part1[i];
}
}
file.Close();
}
char[] delimiter2 = new char[] { '\t' };
for (int j = 4; j < sepList.Count; j++)
{
st = sepList[j];
string[] part2 = st.Split(delimiter2, StringSplitOptions.RemoveEmptyEntries);
alist.Add(part2);
}
//DateTime time = new DateTime();
//float value = new float();
string tagname = alist[0][0];
for (int y = 0; y < alist.Count; y++)
{
if (alist[y][0]==tagname)
{
alist1.Add(alist[y]);
}
else
{
SensorProbeDataContainer sensorprobe = new SensorProbeDataContainer();
sensorprobe.Setdata(templist);
sensorprobe.SensorProbe = sensorprobe.data[0][0];
ProbeList.Add(sensorprobe.SensorProbe);
DateTime.TryParse(sensorprobe.data[0][2], out sensorprobe.StartDate);
DateTime.TryParse(sensorprobe.data[(sensorprobe.data.Count - 1)][2], out sensorprobe.EndDate);
classcontainer.Add(sensorprobe);
tagname = alist[y][0];
templist.Clear(); }
}
I am trying to follow it on this thread - https://stackoverflow.com/questions/10719396/iterating-separating-list-of-string-arrays-based-on-first-element
Thanks all for the help. Please do point out if you spot any mistakes in code.

Create 2D array from txt file

Okay so I've managed to read in a .txt file... now I'm trying to figure the best way to convert this information into a 2D array.
My text file (first two number provide height and width):
5
5
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
0,1,1,1,0
1,1,1,1,1
My C# / XNA:
string fileContents = string.Empty;
try
{
using (StreamReader reader = new StreamReader("Content/map.txt"))
{
fileContents = reader.ReadToEnd().ToString();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Now what I need to do next is define the size of the 2-dimensional map array and then populate the entry values... this is where I'm getting a bit stuck and have found various ways I can loop through the data but I don't think any of them have been terribly tidy.
What I've tried to do is have one loops which splits by newline... and then another loop which splits by comma delimiter.
Is this the best way to do it... or are there better alternatives?
It can be done with LINQ but that is only practical when you want (accept) an array-of-array, int[][] instead of a straight 2-dimensional int[,] .
int[][] data =
File.ReadLines(fileName)
.Skip(2)
.Select(l => l.Split(',').Select(n => int.Parse(n)).ToArray())
.ToArray();
The code below doesn't require the first to rows in your sample .CSV file:
5
5
I'd prefer it this way, but as a consequence, the code below reads the file twice. It would take a small modification use the first two rows in your sample instead.
private int[,] LoadData(string inputFilePath)
{
int[,] data = null;
if (File.Exists(inputFilePath))
{
Dictionary<string, int> counts = GetRowAndColumnCounts(inputFilePath);
int rowCount = counts["row_count"];
int columnCount = counts["column_count"];
data = new int[rowCount, columnCount];
using (StreamReader sr = File.OpenText(inputFilePath))
{
string s = "";
string[] split = null;
for (int i = 0; (s = sr.ReadLine()) != null; i++)
{
split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
for (int j = 0; j < columnCount; j++)
{
data[i, j] = int.Parse(split[j]);
}
}
}
}
else
{
throw new FileDoesNotExistException("Input file does not exist");
}
return data;
}
private Dictionary<string, int> GetRowAndColumnCounts(string inputFilePath)
{
int rowCount = 0;
int columnCount = 0;
if (File.Exists(inputFilePath))
{
using (StreamReader sr = File.OpenText(inputFilePath))
{
string[] split = null;
int lineCount = 0;
for (string s = sr.ReadLine(); s != null; s = sr.ReadLine())
{
split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (columnCount == 0)
{
columnCount = split.Length;
}
lineCount++;
}
rowCount = lineCount;
}
if (rowCount == 0 || columnCount == 0)
{
throw new FileEmptyException("No input data");
}
}
else
{
throw new FileDoesNotExistException("Input file does not exist");
}
Dictionary<string, int> counts = new Dictionary<string, int>();
counts.Add("row_count", rowCount);
counts.Add("column_count", columnCount);
return counts;
}
Here's the solution I've come up with which appears to work.
int[,] txtmap;
int height = 0;
int width = 0;
string fileContents = string.Empty;
try
{
using (StreamReader reader = new StreamReader("Content/map.txt"))
{
fileContents = reader.ReadToEnd().ToString();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
string[] parts = fileContents.Split(new string[] { "\r\n" }, StringSplitOptions.None);
for (int i = 0; i < parts.Length; i++)
{
if (i == 0)
{
// set width
width = Int16.Parse(parts[i]);
}
else if (i == 1)
{
// set height
height = Int16.Parse(parts[i]);
txtmap = new int[width, height];
}
if (i > 1)
{
// loop through tiles and assign them as needed
string[] tiles = parts[i].Split(new string[] { "," }, StringSplitOptions.None);
for (int j = 0; j < tiles.Length; j++)
{
txtmap[i - 2, j] = Int16.Parse(tiles[j]);
}
}
}

Categories