loading CSV data and create array of points - c#

I'm currently tasked with creating a small C# application in Visual C# 2010 Express that loads a CSV file and processes the information to create an array of points, to be displayed on a map.
The entries in the CSV are as follows:
Device;Latitude;Longitude;Speed;Time
57EA7531-0E1F-41C7-B785-22398D445FEA;55.512.653;13.306.292;93;13-4-2014 14:01
The idea is to load this information, split the data, appoint it to different attributes of the following code:
ShapeLayer sl = new ShapeLayer("Marker");
wpfMap.Layers.Add(sl);
marker.Width = marker.Height = 20;
marker.ToolTip = "A map marker"; [needs to contain Device;Latitude;Longitude;Speed;Time]
sl.Shapes.Add(marker);
ShapeCanvas.SetLocation(marker, new System.Windows.Point(8.4, 49)); [needs to contain Longitude,Latitude]
noted inbetween [] is the data from the CSV that needs to be entered.
This CSV file contains about 2000 entries and for each entry, a points needs to be created using the above code. I have very limited experience with loading CSV's and creating an Array with the processed data, is there ayone that can help me out?

There are different ways. I will do something like that.
NOTE. Exception handling will be required in this solution.
string[] allLines = System.IO.File.ReadAllLines(#"yourCVSPath.csv");
foreach(string sLine in allLines)
{
string[] arrLine = sLine.Split(new char[] { ',' }); // or ';' according to provided data
if (arrLine.Length == 5)
{
string sDevice = arrLine[0];
string sLatitude = arrLine[1];
string sLongitude = arrLine[2];
string sSpeed = arrLine[3];
string sTime = arrLine[4];
ShapeLayer sl = new ShapeLayer("Marker");
wpfMap.Layers.Add(sl);
marker.Width = marker.Height = 20;
marker.ToolTip = sLine; //[needs to contain Device;Latitude;Longitude;Speed;Time]
sl.Shapes.Add(marker);
ShapeCanvas.SetLocation(marker, new System.Windows.Point(sLongitude, sLatitude)); //[needs to contain Longitude,Latitude]
}
}

Related

How to test every value from string array in c#?

Hello I am makimg a firmware check program. And the firmware URL has a bunch of diffrent region URL's. For example AFG TMC EGY. And these all must go at the ending of URL, but I dont want to rewrite the code 3 times. How do I make this into a array and make the app test every of off those region codes.
P.S Im a newbie. I have created the array but further i do not know.
string[] regions = new string[3];
regions[0] = "AFG";
regions[1] = "TMC";
regions[2] = "EGY";
If you are loooking to append the three regions to a url to check against .. you can run the following loop.
string[] regions = new string[3];
regions[0] = "AFG";
regions[1] = "TMC";
regions[2] = "EGY";
foreach(string region in regions)
{
Console.WriteLine($"https://url.com/{region}");
}
// output:
https://url.com/AFG
https://url.com/TMC
https://url.com/EGY
In your code, you would do what you need to do with the URL (instead of simply printing it).
Less code:
var regions = new[] { "AFG", "TMC", "EGY" };
Array.ForEach(regions, r => Console.WriteLine($"https://url.com/{r}"));
...with an attached counter-argument.

How to insert string of lines and insert each element into different Arrays

Hi I am trying to make an atom simulation application as my school project. I have created Arrays of each element that I will store like in Atomic number the Atomic number will be stored in Symbol H will be stored and so on. I have read the file using stream reader but i am having difficulty reading each element into the right array.
Txt file is here
1,H,Hydrogen,1,1+
3,Li,Lithium,7,1+
11,Na,Sodium,23,1+
19,K,Potassium,39,1+
37,Rb,Rubidium,85,1+
55,Cs,Casesium,133,1+
87,Fr,Francium,223,1+
4,Be,Beryllium,9,2+
12,Mg,Magnesium,24,2+
20,Ca,Calcium,40,2+
38,Sr,Strontium,88,2+
56,Ba,Barium,137,2+
88,Ra,Radium,226,2+
5,B,Boron,10,3+
13,Al,Aluminium,27,3+
31,Ga,Gallium,70,3+
49,In,Indium,115,3+
81,Tl,Thallium,204,3+
6,C,Carbon,12,0
14,Si,Silicon,28,0
32,Ge,Germanium,73,0
50,Sn,Tin,119,0
82,Pb,Lead,207,0
7,N,Nitrogen,14,3-
15,P,Phosphorus,31,3-
33,As,Arsenic,75,3-
51,Sb,Antimony,122,3-
83,Bi,Bismuth,209,3-
8,O,Oxygen,16,2-
16,S,Sulfur,32,2-
34,Se,Selenium,79,2-
52,Te,Tellurium,128,2-
84,Po,Polonium,209,2-
9,F,Fluorine,19,1-
17,Cl,Chlorine,35,1-
35,Br,Bromine,80,1-
53,I,Iodine,127,1-
85,At,Astatine,210,1-
2,He,Helium,4,0
10,Ne,Neon,20,0
18,Ar,Argon,40,0
36,Kr,Kryoton,85,0
54,Xe,Xenon,131,0
86,Rn,Radon,222,0
.
struct TAtom
{
public int atomicNumber;
public string symbol;
public string name;
public int mass;
public string charge;
}
class Atom
{
static void Main(string[] args)
{
{
TAtom[] Atom = new TAtom[44];
Atom[0].atomicNumber = 1;
TAtom[] Symbol = new TAtom[44];
Symbol[1].symbol = "";
TAtom[] Name = new TAtom[44];
Name[2].name = "";
TAtom[] Mass = new TAtom[44];
Mass[3].mass = '1';
TAtom[] Charge = new TAtom[44];
Charge[4].charge = "";
string[] words;
StreamReader File = new StreamReader(#"JUNK1.txt");
while (File.EndOfStream == false)
{
string line = File.ReadLine();
words = line.Split(',');
}
File.Close();
}
}
}
This variable contains the data from a "line" (or "record") in the file:
words = line.Split(',');
And such a record looks like this:
1,H,Hydrogen,1,1+
Assuming that the data is consistent (you'd want to add error-checking in a variety of places if it isn't), then you can construct an instance of TAtom like this:
var atom = new TAtom
{
atomicNumber = int.Parse(words[0]),
symbol = words[1],
name = words[2],
mass = int.Parse(words[3]),
charge = words[4]
};
Potential runtime errors include, but may not be limited to:
Invalid int data would result in an exception from int.Parse(). Look into the use of int.TryParse() as an alternative. It would require a bit of restructuring of this single line of code into multiple lines, reading inputs separately and constructing the TAtom instance at the end.
Incomplete "records" would result in an exception when attempting to access an invalid index on words. You might check the length of words before attempting to use it.
It would be in your best interests to take a look at what your code is doing in a debugger. As you step through each line of code while it's executing, you can see what's in your variables. Examining the runtime contents of words is your biggest clue on how to construct your TAtom instance.
Once you have this instance in the atom variable above, you can add that to any array/list/collection/etc. that you like. (See my comments on the question above regarding your overall design approach.)
I would read the data in first, as you are doing. Since each line is a TAtom, assign a new TAtom to the appropriate indicies of the comma delimited words(line) array, then add the atom you create for each line to an array or arraylist.
List<TAtom> atomList = new List<TAtom>();
StreamReader File = new StreamReader(#"JUNK1.txt");
while (File.EndOfStream == false)
{
string line = File.ReadLine();
TAtom tatom = new TAtom();
words = line.Split(',');
tatom.atomicNumber=words[0]
tatom.symbol=words[1]
tatom.name=words[2]
tatom.mass=words[3]
tatom.charge=words[4]
//add the current line's atom to a data structure
atomList.Add(tatom);
}
File.Close();
Now you can access all of the TAtom structs through the atomList!

parsing text file to data table with irregular rows

i am trying to parse a tabular data in a text file into a data table.
the text file contains text
PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU COMMAND
11 root 1 171 52 0K 12K RUN 23:46 80.42% idle
12 root 1 -20 -139 0K 12K RUN AS 0:56 7.96% swi7:
the code i have is like
public class Program
{
static void Main(string[] args)
{
var lines = File.ReadLines("bb.txt").ToArray();
var headerLine = lines[0];
var dt = new DataTable();
var columnsArray = headerLine.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var dataColumns = columnsArray.Select(item => new DataColumn { ColumnName = item });
dt.Columns.AddRange(dataColumns.ToArray());
for (int i = 1; i < lines.Length; i++)
{
var rowLine = lines[i];
var rowArray = rowLine.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var x = dt.NewRow();
x.ItemArray = rowArray;
dt.Rows.Add(x);
}
}
}
i get an error that "Input array is longer than the number of columns in this table" at second attempt on
x.ItemArray = rowArray;
Off course because second row has "RUN AS" as the value of 8th column. it also has a space between it which is a common split character for the entire row hence creating a mismatch between array's length and columns length.
what is the possible solution for this kind of situation.
Assuming that "RUN AS" is your only string that causes you the condition like this, you could just run var sanitizedLine = rowLine.Replace("RUN AS", "RUNAS") before your split and then separate the words back out afterwards. If this happens more often, however, you may need to set a condition to check that the array generated by the split matches the length of the header, then combine the offending indexes in a new array of the correct length before attempting to add it.
Ideally, however, you would instead have whatever is generating your input file wrap strings in quotes to make your life easier.

CSV change delimiter

i'm reading a CSV file and changing the delimiter from a "," to a "|". However i've noticed in my data (which I have no control over) that in certain cases I have some data that does not want to follow this rule and it contains quoted data with a comma in it. I'm wondering how best to not replace these exceptions?
For example:
ABSON TE,Wick Lane,"Abson, Pucklechurch",Bristol,Avon,ENGLAND,BS16
9SD,37030,17563,BS0001A1,,
Should be changed to:
ABSON TE|Wick Lane|"Abson, Pucklechurch"|Bristol|Avon|ENGLAND|BS16
9SD|37030|17563|BS0001A1||
The code to read and replace the CSV file is this:
var contents = File.ReadAllText(filePath).Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToArray();
var formattedContents = contents.Select(line => line.Replace(',', '|'));
For anyone else struggling with this, I ended up using the built in .net csv parser. See here for more details and example: http://coding.abel.nu/2012/06/built-in-net-csv-parser/
My specific code:
// Create new parser object and setup parameters
var parser = new TextFieldParser(new StringReader(File.ReadAllText(filePath)))
{
HasFieldsEnclosedInQuotes = true,
Delimiters = new string[] { "," },
TrimWhiteSpace = true
};
var csvSplitList = new List<string>();
// Reads all fields on the current line of the CSV file and returns as a string array
// Joins each field together with new delimiter "|"
while (!parser.EndOfData)
{
csvSplitList.Add(String.Join("|", parser.ReadFields()));
}
// Newline characters added to each line and flattens List<string> into single string
var formattedCsvToSave = String.Join(Environment.NewLine, csvSplitList.Select(x => x));
// Write single string to file
File.WriteAllText(filePathFormatted, formattedCsvToSave);
parser.Close();

Read a CSV file in to an array using C#

I am trying to write code that will pull in, read, and separate a csv file. It has four columns with no titles. I've been searching for hours online and no one really seems to have the answer so I'm hoping that someone here can. After it is read in I need it to be able to be pulled very specifically as it is part of design. Thanks ahead of time!
Your question is a little vague, but I'll try and answer it as best I can.
A CSV file is (by definition) a file containing comma seperated values - the key here is that a comma is used as the delimiter. Personally, I find that using a different delimiter is prone to less nasties when parsing.
I've created the following test CSV file:
Column1,Column2,Column3,Column4
Row1Value1,Row1Value2,Row1Value3,Row1Value4
Row2Value1,Row2Value2,Row2Value3,Row2Value4
Row3Value1,Row3Value2,Row3Value3,Row3Value4
Row4Value1,Row4Value2,Row4Value3,Row4Value4
Row5Value1,Row5Value2,Row5Value3,Row5Value4
Here's some code to read that file into some simple structures that you can then manipulate. You might want to extend this code by creating classes for the columns and rows (and values as well).
string sFileContents = "";
using (StreamReader oStreamReader = new StreamReader(File.OpenRead("Test.csv")))
{
sFileContents = oStreamReader.ReadToEnd();
}
List<string[]> oCsvList = new List<string[]>();
string[] sFileLines = sFileContents.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (string sFileLine in sFileLines)
{
oCsvList.Add(sFileLine.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
}
int iColumnNumber = 0;
int iRowNumber = 0;
Console.WriteLine("Column{0}, Row{1} = \"{2}\"", iColumnNumber, iRowNumber, oCsvList[iColumnNumber][iRowNumber]);
iColumnNumber = 4;
iRowNumber = 2;
Console.WriteLine("Column{0}, Row{1} = \"{2}\"", iColumnNumber, iRowNumber, oCsvList[iColumnNumber][iRowNumber]);
Keep in mind that values are accessed by the column number, and then the row number.
I hope this helps.
All you need to do is simply convert it into a byte[] array and back into a string[builder?]. Then seperate each entry, and parse it like so.
http://www.digitalcoding.com/Code-Snippets/C-Sharp/C-Code-Snippet-Convert-file-to-byte-array.html
And to convert to a string:
// C# to convert a byte array to a string.
byte [] dBytes = ...
string str;
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
str = enc.GetString(dBytes);
You have to understand you need to make a parser. I made one to pull in Yahoo Stocks, basically splitting the colons into data.
This is a much simpler way to do what you want.
var lineCount = File.ReadLines(#"C:\file.txt").Count();
var reader = new StreamReader(File.OpenRead(#"C:\location1.csv"));
int[,] properties = new int[lineCount,4];
for(int i2 = 0; i2 < 4; i2++)
{
for(int i = 0; i < lineCount; i++)
{
var line = reader.ReadLine();
var values = line.Split(';');
properties[i,i2] = Convert.ToInt32(values[i2];
}
}

Categories

Resources