C# Read file, split at ; write in array - c#

so I have a file like this:
1;2;5
1;3;3
1;4;3
1;5;1
1;6;0
and I want every number as easy accassible as possibe
so I thought multi dimentional array
that's the idea so far:
System.IO.StreamReader file = new System.IO.StreamReader(#"C:\Users\Hisfantor\Desktop\transport.txt");
int count = 0;
string linee;
string line;
string[] extract;
while ((linee = file.ReadLine()) != null)
{
count++;
}
textBox1.Text = Convert.ToString(count);
double[,] destinations = new double[(int)count, 3];
for (int i = 0; i < count; i++)
{
line = file.ReadLine();
extract = line.Split(';');
destinations[i, 1] = Convert.ToDouble(extract[0]);
destinations[i, 2] = Convert.ToDouble(extract[1]);
destinations[i, 3] = Convert.ToDouble(extract[2]);
listBox1.Items.Add(destinations[i, 1]);
}
file.Close();
I tried different things, but never get anything in the listbox(just for testing)

Try this:
using System.IO.StreamReader file = new System.IO.StreamReader(#"C:\Users\Hisfantor\Desktop\transport.txt");
int count = 0;
string line;
string[] extract;
while ((line = file.ReadLine()) != null)
{
extract = line.Split(';');
var lineValue = new LineValue()
{
Col1 = Convert.ToDouble(extract[0]),
Col2 = Convert.ToDouble(extract[1]),
Col3 = Convert.ToDouble(extract[2]),
};
listBox1.Items.Add(lineValue);
count++;
}
textBox1.Text = Convert.ToString(count);
public class LineValue
{
public double Col1 { get; set; }
public double Col2 { get; set; }
public double Col3 { get; set; }
public override string ToString() => $"{Col1};{Col2};{Col3}";
}

I suggest jagged array, i.e. array of array double[][] instead of 2D one (double[,]). Then you can query the file with a help of Linq:
using System.Linq;
...
double[][] destinations = File
.ReadLines(#"C:\Users\Hisfantor\Desktop\transport.txt")
.Where(line => !string.IsNullOrWhiteSpace(line))
.Select(line => line
.Split(';')
.Select(item => double.Parse(item))
.ToArray())
.ToArray();
foreach (var array in destinations)
listBox1.Items.Add(array[1]);

This is how I would approach it.
class Item
{
public int Value1 { get; set; }
public int Value2 { get; set; }
public int Value3 { get; set; }
}
string line;
List<Item> items = new List<Item>();
using (StreamReader reader = new StreamReader(path))
{
while ((line = reader.ReadLine()) != null)
{
string[] tokens = line.Split(';');
if (tokens.Length == 3)
{
int value;
Item item = new Item();
item.Value1 = int.TryParse(tokens[0], out value) ? value : 0;
item.Value2 = int.TryParse(tokens[1], out value) ? value : 0;
item.Value3 = int.TryParse(tokens[2], out value) ? value : 0;
items.Add(item);
}
}
}
This code reads a line at a time and populates a list of Items as it reads them. It includes error checking to avoid unexpected exceptions due to invalid inputs.
Also, you should wrap StreamReader in a using block to ensure it cleans up in a timely manner, even if an exception exits your method prematurely.

Related

binary search in a sorted list in c#

I am retrieving client id\ drum id from a file and storing them in a list.
then taking the client id and storing it in another list.
I need to display the client id that the user specifies (input_id) on a Datagrid.
I need to get all the occurrences of this specific id using binary search.
the file is already sorted.
I need first to find the occurrences of input_id in id_list.
The question is: how to find all the occurrences of input_id in the sorted list id_list using binary search?
using(StreamReader sr= new StreamReader(path))
{
List<string> id_list = new List<string>();
List<string> all_list= new List<string>();
List<int> indexes = new List<int>();
string line = sr.ReadLine();
line = sr.ReadLine();
while (line != null)
{
all_list.Add(line);
string[] break1 = line.Split('/');
id_list.Add(break1[0]);
line = sr.ReadLine();
}
}
string input_id = textBox1.Text;
Data in the file:
client id/drum id
-----------------
123/321
231/3213
321/213123 ...
If the requirement was to use binary search I would create a custom class with a comparer, and then find an element and loop forward/backward to get any other elements. Like:
static void Main(string[] args
{
var path = #"file path...";
// read all the Ids from the file.
var id_list = File.ReadLines(path).Select(x => new Drum
{
ClientId = x.Split('/').First(),
DrumId = x.Split('/').Last()
}).OrderBy(o => o.ClientId).ToList();
var find = new Drum { ClientId = "231" };
var index = id_list.BinarySearch(find, new DrumComparer());
if (index != -1)
{
List<Drum> matches = new List<Drum>();
matches.Add(id_list[index]);
//get previous matches
for (int i = index - 1; i > 0; i--)
{
if (id_list[i].ClientId == find.ClientId)
matches.Add(id_list[i]);
else
break;
}
//get forward matches
for (int i = index + 1; i < id_list.Count; i++)
{
if (id_list[i].ClientId == find.ClientId)
matches.Add(id_list[i]);
else
break;
}
}
}
public class Drum
{
public string DrumId { get; set; }
public string ClientId { get; set; }
}
public class DrumComparer : Comparer<Drum>
{
public override int Compare(Drum x, Drum y) =>
x.ClientId.CompareTo(y.ClientId);
}
If i understand you question right then this should be a simple where stats.
// read all the Ids from the file.
var Id_list = File.ReadLines(path).Select(x => new {
ClientId = x.Split('/').First(),
DrumId = x.Split('/').Last()
}).ToList();
var foundIds = Id_list.Where(x => x.ClientId == input_id);

Read lines of data from CSV then display data

I have to read info from a txt file, store it in a manner (array or list), then display the data. Program must include at least one additional class.
I've hit a wall and can't progress.
string, string, double, string
name,badge,salary,position
name,badge,salary,position
name,badge,salary,position
I'm sorry and I know the code below is disastrous but I'm at a loss and am running out of time.
namespace Employees
{
class Program
{
static void Main()
{
IndividualInfo collect = new IndividualInfo();
greeting();
collect.ReadInfo();
next();
for (int i = 0; i < 5; i++)
{
displayInfo(i);
}
exit();
void greeting()
{
Console.WriteLine("\nWelcome to the Software Development Company\n");
}
void next()
{
Console.WriteLine("\n*Press enter key to display information . . . *");
Console.Read();
}
void displayInfo(int i)
{
Console.WriteLine($"\nSoftware Developer {i + 1} Information:");
Console.WriteLine($"\nName:\t\t\t{collect.nameList[i]}");
}
void exit()
{
Console.WriteLine("\n\n*Press enter key to exit . . . *");
Console.Read();
Console.Read();
}
}
}
}
class IndividualInfo
{
public string Name { get; set; }
//public string Badge{ get; set; }
//public string Position{ get; set; }
//public string Salary{ get; set; }
public void ReadInfo()
{
int i = 0;
string inputLine;
string[] eachLine = new string[4];
string[,] info = new string[5, 4]; // 5 developers, 4x info each
StreamReader file = new StreamReader("data.txt");
while ((inputLine = file.ReadLine()) != null)
{
eachLine = inputLine.Split(',');
for (int x = 0; x < 5; x++)
{
eachLine[x] = info[i, x];
x++;
}
i++;
}
string name = info[i, 0];
string badge = info[i, 1];
string position = info[i, 2];
double salary = Double.Parse(info[i, 3]);
}
public List<string> nameList = new List<string>();
}
So far I think I can collect it with a two-dimensional array, but a List(s) would be better. Also, the code I've posted up there won't run because I can't yet figure out a way to get it to display. Which is why I'm here.
using System.IO;
static void Main(string[] args)
{
using(var reader = new StreamReader(#"C:\test.csv"))
{
List<string> listA = new List<string>();
List<string> listB = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
listA.Add(values[0]);
listB.Add(values[1]);
}
}
}
https://www.rfc-editor.org/rfc/rfc4180
or
using Microsoft.VisualBasic.FileIO;
var path = #"C:\Person.csv"; // Habeeb, "Dubai Media City, Dubai"
using (TextFieldParser csvParser = new TextFieldParser(path))
{
csvParser.CommentTokens = new string[] { "#" };
csvParser.SetDelimiters(new string[] { "," });
csvParser.HasFieldsEnclosedInQuotes = true;
// Skip the row with the column names
csvParser.ReadLine();
while (!csvParser.EndOfData)
{
// Read current line fields, pointer moves to the next line.
string[] fields = csvParser.ReadFields();
string Name = fields[0];
string Address = fields[1];
}
}
http://codeskaters.blogspot.ae/2015/11/c-easiest-csv-parser-built-in-net.html
or
LINQ way:
var lines = File.ReadAllLines("test.txt").Select(a => a.Split(';'));
var csv = from line in lines
select (from piece in line
select piece);
^^Wrong - Edit by Nick
It appears the original answerer was attempting to populate csv with a 2 dimensional array - an array containing arrays. Each item in the first array contains an array representing that line number with each item in the nested array containing the data for that specific column.
var csv = from line in lines
select (line.Split(',')).ToArray();
This question was fully addressed here:
Reading CSV file and storing values into an array

How to collect array of matched value from string?

I am filling data from memory mapped file to string like :
AAPL,2013-1-2
Open:79.117
Close:78.433
High:79.286
Low:77.376
Volume:139948984
AAPL,2013-1-3
Open:78.268
Close:77.442
High:78.524
Low:77.286
Volume:88114464
and so on...
So now I want to make an array of close value of all days. And there are collection of thousands of days data in memory mapped file and string. So how can I fetch close value and can make array of its?
I am trying to make it's array but it's make whole data into single array. So it's not what i want.
string[] lines = System.IO.File.ReadAllLines(#"D:\mine.txt");
foreach (string line in lines)
{
// Use a tab to indent each line of the file.
Console.WriteLine("\t" + line);
}
byte[] bytes = new byte[10000000];
stream.ReadArray(0, bytes, 0, bytes.Length);
string txt = Encoding.UTF8.GetString(bytes).Trim('\0');`
So I need an array of all close value to fetch from that string. Like that:
{78.433, 77.442, etc..}
Try this:
decimal[] arrayOfCloses =
File
.ReadAllLines(#"D:\mine.txt")
.Select(x => x.Split(':'))
.Where(x => x.Length == 2)
.Where(x => x[0] == "Close")
.Select(x => decimal.Parse(x[1]))
.ToArray();
Try this:
File.ReadLines(#"D:\mine.txt")
// Pick only those lines starting with "Close"
.Where(line => line.StartsWith("Close:"))
// Get value, which follows colon, and parse it do double
.Select(line => double.Parse(line.Split(':')[1]))
// Convert result to an array
.ToArray();
I supposed your file Like this :
AAPL,2013-1-2
Open:79.117
Close:78.433
High:79.286
Low:77.376
Volume:139948984
AAPL,2013-1-3
Open:78.268
Close:77.442
High:78.524
Low:77.286
Volume:88114464
Try this
var lines = System.IO.File.ReadAllLines(#"C:\Users\bouyami\Documents\AB_ATELIER\1.txt").ToList();
var linesFiltred = lines.Where(x => x.StartsWith("Close")).ToList();
var result = linesFiltred.Select(x => x.Split(':')[1]).ToList();
Try following which accepts blank lines :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication98
{
class Program
{
const string FILENAME = #"c:\temp\test.txt";
static void Main(string[] args)
{
AAPL aapl = new AAPL(FILENAME);
}
}
public class AAPL
{
static List<AAPL> aapls = new List<AAPL>();
private DateTime date { get; set; }
public decimal open { get; set; }
public decimal close { get; set; }
public decimal low { get; set; }
public decimal high { get; set; }
public int volume { get; set; }
public AAPL() { }
public AAPL(string filename)
{
StreamReader reader = new StreamReader(filename);
string line = "";
AAPL newAAPL = null;
while ((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length > 0)
{
if (line.StartsWith("AAPL"))
{
string dateStr = line.Substring(line.IndexOf(",") + 1);
date = DateTime.Parse(dateStr);
newAAPL = new AAPL();
aapls.Add(newAAPL);
newAAPL.date = date;
}
else
{
string[] splitArray = line.Split(new char[] { ':' });
switch (splitArray[0])
{
case "Open":
newAAPL.open = decimal.Parse(splitArray[1]);
break;
case "Close":
newAAPL.close = decimal.Parse(splitArray[1]);
break;
case "Low":
newAAPL.low = decimal.Parse(splitArray[1]);
break;
case "High":
newAAPL.high = decimal.Parse(splitArray[1]);
break;
case "Volume":
newAAPL.volume = int.Parse(splitArray[1]);
break;
}
}
}
}
}
}
}

"Object reference not set to an instance of an object" error during the compilation

I get the "Object reference not set to an instance of an object" error when i compile the code at string[] values = lineuser.Split(' '); . Any idea?
namespace function
{
public partial class Form1 : Form
{
float userscore,itemscore,result;
string lineitem, lineuser;
//float[][] a = new float[89395][100];
//float[][] b = new float[1143600][100];
float[][] a = Enumerable.Range(0, 89395).Select(i => new float[100]).ToArray();
float[][] b = Enumerable.Range(0, 1143600).Select(j => new float[100]).ToArray();
//float[,] c = new float[89395, 100];
StreamReader fileitem = new StreamReader("c:\\ITEM_SVD_FULL.txt");
StreamReader fileuser = new StreamReader("c:\\USER_SVD_FULL.txt");
public Form1()
{
InitializeComponent();
for (int x = 0; x <= 8939500; x++)
{
lineuser = fileuser.ReadLine();
string[] values = lineuser.Split(' '); //<------the line's error
int userid, factoriduser;
foreach (string value in values)
{
userid = Convert.ToInt32(values[0]);
factoriduser = Convert.ToInt32(values[1]);
userscore = Convert.ToSingle(values[2]);
a[userid][factoriduser] = userscore;
}
}
for (int y = 0; y <= 114360000; y++)
{
lineitem = fileitem.ReadLine();
string[] valuesi = lineitem.Split(' ');
int itemid, factoriditem;
foreach (string value in valuesi)
{
itemid = Convert.ToInt32(valuesi[0]);
factoriditem = Convert.ToInt32(valuesi[1]);
itemscore = Convert.ToSingle(valuesi[2]);
b[itemid][factoriditem] = itemscore;
}
}
}
public float dotproduct(int userid,int itemid)
{
//get the score of 100 from user and item to dotproduct
float[] u_f = a[userid];
float[] i_f = b[itemid];
for (int i = 0; i <u_f.GetLength(1); i++)
{
result += u_f[userid] * i_f[itemid];
}
return result;
}
private void btn_recomm_Click(object sender, EventArgs e)
{
if(txtbx_id.Text==null)
{
MessageBox.Show("please insert user id");
}
if (txtbx_id.Text != null && txtbx_itemid==null)
{
int sc = Convert.ToInt32(txtbx_id.Text);
if (sc>=0 &&sc<=89395)
{
for (int z=0;z<=1143600;z++)
{
dotproduct(sc,z);
}
//Hashtable hashtable = new Hashtable();
//put the result in hashtable
//foreach (DictionaryEntry entry in hashtable)
//{
//Console.WriteLine("{0}, {1}", entry.Key, entry.Value);
// }
}
}
if (txtbx_id!=null &&txtbx_itemid!=null)
{
int uid = Convert.ToInt32(txtbx_id.Text);
int iid = Convert.ToInt32(txtbx_itemid.Text);
{
if (uid>=0 && uid<=89395 && iid>=0 && iid<=1143600)
{
dotproduct(uid,iid);
MessageBox.Show("The Score of user id "+uid+" is "+result);
}
}
Please check you lineuser variable is null
public Form1()
{
InitializeComponent();
for (int x = 0; x <= 8939500; x++)
{
if(!string.IsNullorEmpty(lineuser) //<--- check the string is empty
{
string[] values = lineuser.Split(' '); //<------the line's error
int userid, factoriduser;
foreach (string value in values)
{
userid = Convert.ToInt32(values[0]);
factoriduser = Convert.ToInt32(values[1]);
userscore = Convert.ToSingle(values[2]);
a[userid][factoriduser] = userscore;
}
}
}
for (int y = 0; y <= 114360000; y++)
{
lineitem = fileitem.ReadLine();
if(!string.IsNullorEmpty(lineitem) //<--- check the string is empty
{
string[] valuesi = lineitem.Split(' ');
int itemid, factoriditem;
foreach (string value in valuesi)
{
itemid = Convert.ToInt32(valuesi[0]);
factoriditem = Convert.ToInt32(valuesi[1]);
itemscore = Convert.ToSingle(valuesi[2]);
b[itemid][factoriditem] = itemscore;
}
}
}
}
Now you can avoid the error.
You haven't opened the Stream fileuser so it is still null.
It is really a bad practice to open the file while you define the global variable in your class.
But as part from this, when you call ReadLine the result could be a null because there are no more lines to read and you don't check for this case.
Looking at the code shown above, there is no need to have a global variable for the filestream, so, the usual pattern when handling resources (OPEN/USE/CLOSE) should be followed for both files
public Form1()
{
InitializeComponent();
string lineuser;
// OPEN
using(StreamReader fileuser = new StreamReader("c:\\USER_SVD_FULL.txt"))
{
// USE
while((lineuser = fileuser.ReadLine()) != null)
{
string[] values = lineuser.Split(' ');
....
}
} //CLOSE & DISPOSE
....
string lineitem;
using(StreamReader fileitem = new StreamReader("c:\\ITEM_SVD_FULL.txt"))
{
while((lineitem = fileitem.ReadLine()) != null)
{
string[] valuesi = lineitem.Split(' ');
....
}
}

read large text file into array with specific format

I have a text file with the following format of information:
1 1.2323232 2.2356 4.232 1.23664
2 1.344545
3 6.2356 7.56455212
etc....
How do I read the file in C#, parse it into an array, then do some processing on it?
Use File Helpers.
For eg. All you would need is to define the record parsing as this :
[DelimitedRecord("|")]
public class Orders
{
public int OrderID;
public string CustomerID;
[FieldConverter(ConverterKind.Date, "ddMMyyyy")] public DateTime OrderDate;
public decimal Freight;
}
And read the file in as this :
FileHelperEngine engine = new FileHelperEngine(typeof(Orders));
// to Read use:
Orders[] res = engine.ReadFile("TestIn.txt") as Orders[];
// to Write use:
engine.WriteFile("TestOut.txt", res);
You could change the delimiter to " " & suitably update the member types as well.
Hey your code looks like there is an ID value at position one. So I created some example code.
private List<MyValues> Read(string fileName)
{
var result = new List<MyValues>();
var line = new string[] { };
using (StreamReader sr = new StreamReader(fileName))
{
while (sr.Peek() > -1)
{
line = sr.ReadLine().Trim().Split(' ');
var val = new MyValues();
val.Id = Convert.ToInt32(line.ElementAt(0));
for (int n = 1; n < line.Count(); n++)
{
val.Values.Add(Convert.ToDouble(line[n]));
}
result.Add(val);
}
}
return result;
}
class MyValues
{
public int Id = 0;
public List<double> Values = new List<double>();
}

Categories