Why is my array appearing as never assigned to? - c#

I am currently working on a project that involves taking a text file with information in it and storing the values into an array for use in determining if a certain book should be "split" based on its ID.
I have declared a string array in the class that is executing the method for this task, and assigning the values from the text file using a StreamReader.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Odbc;
using System.Data.OleDb;
using System.IO;
namespace ElectionsPollBooks
{
class dbElections
{
//arrays, ints, for pollbook splits
string[] as_splitNumbers;
int i_splitCount;
public void Process()
{
//opens conenction
OpenConn();
//Gets the precinct info for later parsing
GetDistrictInfo();
//populate splits array
PopulateSplits();
//the hard work
SeperateDataSet();
CloseConn();
}
//...other methods in here, not related
private void PopulateSplits()
{
//sets the count
i_splitCount = 0;
//reads the split file
StreamReader sr_splits = new StreamReader(#"a\file\path\here\.txt");
//begin populating the array
while (sr_splits.ReadLine() != null)
{
//split ID
as_splitNumbers[i_splitCount] = sr_splits.ReadLine();
i_splitCount = i_splitCount + 1;
}
sr_splits.Close();
sr_splits.Dispose();
}
}
}
Visual Studio is telling me at this line:
string[] as_splitNumbers;
That:
"as_splitNumbers is never assigned to and will always return a null value."
When I also run the program, it throws a NullReferenceException during the while loop.
My question is then, what am I doing wrong when it comes to assigning the StreamReader values to the as_splitNumbers array? What am I missing in my logic?
Thank you.

You're not initializing your array with a size.
What you could do if you don't know the size is use List<int>.
Change
string[] as_splitNumbers
to
List<string> as_SplitNumbers = new List<string>();
and your method to:
private void PopulateSplits()
{
//sets the count
i_splitCount = 0;
//reads the split file
using(StreamReader sr_splits = new StreamReader(#"a\file\path\here\.txt"))
{
//begin populating the array
while (sr_splits.ReadLine() != null)
{
//split ID
string split = sr_splits.ReadLine();
as_splitNumbers.Add(split);
i_splitCount = i_splitCount + 1;
}
}
}
If what you're sending it to (SeperateDataSet();?) requires an array, you can cast it by using _asSplitNumbers.ToArray() later on. List<T> just allows you to add without knowing the size.

Try to use a List (System.Enumerable).
Because you donn't know the size of the array before reading.
At the declaration of the variable it will means:
List<string> as_splitNumbers = new List<string>();
in the loop you can simply write
as_splitNumbers.Add(sr_splits.ReadLine())
and it will work!

Your as_splitNumbers array is never allocated. You need to initialize the array with a size first.
string[] as_splitNumbers = new string[SIZE];
However, it seems you should just use a List in your case.
List<string> as_splitNumbers = new List<string>();
Then
//split ID
as_splitNumbers.Add(sr_splits.ReadLine());

Related

Can I create some components with a dynamic name on c#? [duplicate]

Can we create dynamic variable in C#?
I know my below code is threw error and very poor coding. But this code have small logic like create dynamic variable
var name=0;
for(i=0;i<10;i++)// 10 means grid length
{
name+i=i;
}
var xx1=name1;
var xx2=name2;
var xx3=name3;
Is it possible in c#? Create dynamic variable in c#? and change the variable name in c#? and concatenate the variable name in c#(like we can concatenate any control id or name)...
Why I need the dynamic variable name (scenario):
var variablename=""
var variablename0=No;
var variablename1=Yes;
var variablename2=No;
.
.
.
I have a gridview with multiple rows. And I need assign server side variable to every row. So I need set of variables in server side. the only I can set Text=<%# variablename+rowCount%> for every template field.
This rowCount means every grid row index.
If the grid has 2 rows, Then rowCount values are 0,1,2
Now I need to change the variablename to variablename0,variablename1,variablename2 dynamically for separate row.
C# is strongly typed so you can't create variables dynamically. You could use an array but a better C# way would be to use a Dictionary as follows. More on C# dictionaries here.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QuickTest
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, int> names = new Dictionary<string,int>();
for (int i = 0; i < 10; i++)
{
names.Add(String.Format("name{0}", i.ToString()), i);
}
var xx1 = names["name1"];
var xx2 = names["name2"];
var xx3 = names["name3"];
}
}
}
No. That is not possible. You should use an array instead:
name[i] = i;
In this case, your name+i is name[i].
Variable names should be known at compile time. If you intend to populate those names dynamically at runtime you could use a List<T>
var variables = List<Variable>();
variables.Add(new Variable { Name = inputStr1 });
variables.Add(new Variable { Name = inputStr2 });
here input string maybe any text or any list
try this one, user json to serialize and deserialize:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
namespace ConsoleApplication1
{
public class Program
{
static void Main(string[] args)
{
object newobj = new object();
for (int i = 0; i < 10; i++)
{
List<int> temp = new List<int>();
temp.Add(i);
temp.Add(i + 1);
newobj = newobj.AddNewField("item_" + i.ToString(), temp.ToArray());
}
}
}
public static class DynamicExtention
{
public static object AddNewField(this object obj, string key, object value)
{
JavaScriptSerializer js = new JavaScriptSerializer();
string data = js.Serialize(obj);
string newPrametr = "\"" + key + "\":" + js.Serialize(value);
if (data.Length == 2)
{
data = data.Insert(1, newPrametr);
}
else
{
data = data.Insert(data.Length-1, ","+newPrametr);
}
return js.DeserializeObject(data);
}
}
}
This is not possible, it will give you a compile time error,
You can use array for this type of requirement .
For your Reference :
http://msdn.microsoft.com/en-us/library/aa288453%28v=vs.71%29.aspx

Only returning a singular character

Whenever I run this code, it returns one character. I've tried various things, and at most it returns 5 or so lines, each containing one character. I'm trying to find each folder in the "Users" folder, and make my code list them, any help would be appreciated.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
//Search for directories and foreach, try to start discord
try
{
var Bruhm = new List<string>();
Bruhm.Add(Directory.GetDirectories(#"C:\Users\").ToString());
int y = 0;
foreach (string x in Bruhm) {
Console.WriteLine(x[y]);
y = y+1;
}
}
catch(Exception e)
{
Console.WriteLine(e);
System.Threading.Thread.Sleep(-1);
}
System.Threading.Thread.Sleep(-1);
}
}
}
The first mistake you are making is;
Bruhm.Add(Directory.GetDirectories(#"C:\Users\").ToString());
will add only one string, which is System.String[] to your list.
The second mistake is, x[y] will print only one character, which is the character at y index inside the string x.
Change the Add() to AddRange(), and do not call ToString() on your list.
Try this:
var Bruhm = new List<string>();
Bruhm.AddRange(Directory.GetDirectories(#"C:\Users\"));
foreach (string x in Bruhm)
{
Console.WriteLine(x);
}
It's quite simple. You're doing error with this: Directory.GetDirectories(#"C:\Users\").ToString()
Instead try this:
var Bruhm = Directory.GetDirectories(#"C:\Users\");
foreach(var subdir in Bruhm)
Console.WriteLine(subDir);
You are converting a list into a string and printing an index of it and it makes wrong result. You can extract the folder name using this code. "C:\Users\" has removed from the folder's path to provide folders' name not path.
var path = #"C:\Users\";
var Bruhm = Directory.GetDirectories(path).Select(x => x.Substring(path.Length));
foreach (string x in Bruhm)
{
Console.WriteLine(x);
}

Read all values from CSV into a List using CsvHelper

So I've been reading that I shouldn't write my own CSV reader/writer, so I've been trying to use the CsvHelper library installed via nuget. The CSV file is a grey scale image, with the number of rows being the image height and the number columns the width. I would like to read the values row-wise into a single List<string> or List<byte>.
The code I have so far is:
using CsvHelper;
public static List<string> ReadInCSV(string absolutePath)
{
IEnumerable<string> allValues;
using (TextReader fileReader = File.OpenText(absolutePath))
{
var csv = new CsvReader(fileReader);
csv.Configuration.HasHeaderRecord = false;
allValues = csv.GetRecords<string>
}
return allValues.ToList<string>();
}
But allValues.ToList<string>() is throwing a:
CsvConfigurationException was unhandled by user code
An exception of type 'CsvHelper.Configuration.CsvConfigurationException' occurred in CsvHelper.dll but was not handled in user code
Additional information: Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?
GetRecords is probably expecting my own custom class, but I'm just wanting the values as some primitive type or string. Also, I suspect the entire row is being converted to a single string, instead of each value being a separate string.
According to #Marc L's post you can try this:
public static List<string> ReadInCSV(string absolutePath) {
List<string> result = new List<string>();
string value;
using (TextReader fileReader = File.OpenText(absolutePath)) {
var csv = new CsvReader(fileReader);
csv.Configuration.HasHeaderRecord = false;
while (csv.Read()) {
for(int i=0; csv.TryGetField<string>(i, out value); i++) {
result.Add(value);
}
}
}
return result;
}
If all you need is the string values for each row in an array, you could use the parser directly.
var parser = new CsvParser( textReader );
while( true )
{
string[] row = parser.Read();
if( row == null )
{
break;
}
}
http://joshclose.github.io/CsvHelper/#reading-parsing
Update
Version 3 has support for reading and writing IEnumerable properties.
The whole point here is to read all lines of CSV and deserialize it to a collection of objects. I'm not sure why do you want to read it as a collection of strings. Generic ReadAll() would probably work the best for you in that case as stated before. This library shines when you use it for that purpose:
using System.Linq;
...
using (var reader = new StreamReader(path))
using (var csv = new CsvReader(reader))
{
var yourList = csv.GetRecords<YourClass>().ToList();
}
If you don't use ToList() - it will return a single record at a time (for better performance), please read https://joshclose.github.io/CsvHelper/examples/reading/enumerate-class-records
Please try this. This had worked for me.
TextReader reader = File.OpenText(filePath);
CsvReader csvFile = new CsvReader(reader);
csvFile.Configuration.HasHeaderRecord = true;
csvFile.Read();
var records = csvFile.GetRecords<Server>().ToList();
Server is an entity class. This is how I created.
public class Server
{
private string details_Table0_ProductName;
public string Details_Table0_ProductName
{
get
{
return details_Table0_ProductName;
}
set
{
this.details_Table0_ProductName = value;
}
}
private string details_Table0_Version;
public string Details_Table0_Version
{
get
{
return details_Table0_Version;
}
set
{
this.details_Table0_Version = value;
}
}
}
You are close. It isn't that it's trying to convert the row to a string. CsvHelper tries to map each field in the row to the properties on the type you give it, using names given in a header row. Further, it doesn't understand how to do this with IEnumerable types (which string implements) so it just throws when it's auto-mapping gets to that point in testing the type.
That is a whole lot of complication for what you're doing. If your file format is sufficiently simple, which yours appear to be--well known field format, neither escaped nor quoted delimiters--I see no reason why you need to take on the overhead of importing a library. You should be able to enumerate the values as needed with System.IO.File.ReadLines() and String.Split().
//pseudo-code...you don't need CsvHelper for this
IEnumerable<string> GetFields(string filepath)
{
foreach(string row in File.ReadLines(filepath))
{
foreach(string field in row.Split(',')) yield return field;
}
}
static void WriteCsvFile(string filename, IEnumerable<Person> people)
{
StreamWriter textWriter = File.CreateText(filename);
var csvWriter = new CsvWriter(textWriter, System.Globalization.CultureInfo.CurrentCulture);
csvWriter.WriteRecords(people);
textWriter.Close();
}

Unable to order a list using both OrderBy or Sort

So I am trying to sort a file out in a descending order.
The text file looks something like this:
%[TIMESTAMP=1441737006376][EVENT=agentStateEvent][queue=79651][agentID=61871][extension=22801][state=2][reason=0]%
%[TIMESTAMP=1441737006102][EVENT=agentStateEvent][queue=79654][agentID=62278][extension=22828][state=2][reason=0]%
%[TIMESTAMP=1441737006105][EVENT=CallControlTerminalConnectionTalking][callID=2619][ucid=10000026191441907765][deviceType=1][deviceName=21775][Queue=][Trunk=384:82][TrunkType=1][TrunkState=1][Cause=100][CalledDeviceID=07956679058][CallingDeviceID=21775][extension=21775]%
and basically I want the end result to only output unique values of the timestamp. I have used substring to get rid of the excess text, and it outputs fine as shown below:
[TIMESTAMP=1441737006376]
[TIMESTAMP=1441737006102]
[TIMESTAMP=1441737006105]
however i want it to order in the following order (basically numeric descending to ascending):
[TIMESTAMP=1441737006102]
[TIMESTAMP=1441737006105]
[TIMESTAMP=1441737006376]
I have tried the .sort and .orderBy but not having any joy. I wouldve using this prior to doing any substring formatting wouldve sufficed but clearly not.
Code is as follows:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FedSorter
{
class Program
{
static void Main(string[] args)
{
int counter = 0;
string line;
string readIn = "C:\\Users\\xxx\\Desktop\\Files\\ex1.txt";
System.IO.TextWriter writeOut = new StreamWriter("C:\\Users\\xxx\\Desktop\\Files\\ex1_new.txt");
List<String> list = new List<String>();
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader(readIn);
string contents = "";
string checkValues = "";
while ((line = file.ReadLine()) != null)
{
string text = line;
text = text.Substring(1, 25);
if (!checkValues.Contains(text))
{
list.Add(text);
Console.WriteLine(text);
writeOut.WriteLine(text);
counter++;
}
contents = text;
checkValues += contents + ",";
}
list = list.OrderBy(x => x).ToList();
writeOut.Close();
file.Close();
orderingFile();
}
public static void orderingFile()
{
string line = "";
string readIn = "C:\\Users\\xxx\\Desktop\\Files\\ex1_new.txt";
System.IO.TextWriter writeOut = new StreamWriter("C:\\Users\\xxx\\Desktop\\Files\\ex1_new2.txt");
List<String> ordering = new List<String>();
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader(readIn);
while ((line = file.ReadLine()) != null)
{
ordering.OrderBy(x => x).ToList();
ordering.Add(line);
writeOut.WriteLine(line);
}
writeOut.Close();
file.Close();
}
}
}
You are creating a new list and you need to assign it to the variable
list = list.OrderBy(x => x).ToList();
However it doesn't look like you even use list after you create and sort it. Additionally you have the same issue in the orderingFile method with
ordering.OrderBy(x => x).ToList();
However instead of sorting and creating a new list on each line it would be better to use a SortedList<TKey, TValue> that will keep the contents sorted as you add to it.
But again you are not actually using the ordering list after you finish adding to it in the foreach. If you are looking to read the values in a file, sort them and then output them to another file, then you need to do it in that order.
Aside from #juharr's correct answer, you would do well to take advantage of LINQ to simplify your code greatly.
string readIn = "C:\\Users\\xxx\\Desktop\\Files\\ex1.txt";
var timestamps = File.ReadAllLines(readIn)
.Select(l => l.Substring(1, 25))
.Distinct()
.OrderBy(t => t)
.ToArray();
To write out the values, you can either use a foreach on timestamps and write out each line to your TextWriter, or you can use the File class again:
string readOut = "C:\\Users\\xxx\\Desktop\\Files\\ex1_new.txt";
File.WriteAllLines(readOut, timestamps);
//notice I've changed it to ToArray in the first part instead of ToList.

Get variables from text File

I have a text file each item is in <> and they are separated by , there is no spaces.
I need to be able to read total number of records and assign this to a variable.
Also I need to assign each item in a row to a variable and the number of that row to a variable. This is so they can be processed later.
I have search the internet but i just seem to be going in circles, any help or source ideas would be appreciated.
Instructions are not really clear, but i give it a try.
using System;
using System.Data;
using System.IO;
using System.Collections.Generic;
class test
{
public Dictionary<int, String> readAndSortFile()
{
StreamReader sr = new StreamReader("file.txt");
Dictionary<int, String> dic = new Dictionary<int, string>();
int loop = 0;
while (!sr.EndOfStream)
{
dic.Add(loop, sr.ReadLine());
loop++;
}
sr.Close();
return dic;
}
}
your result should look like this:
[0] {[0, <a>]}
[1] {[1, <b>]}
[2] {[2, <c>]}
you can get file like this
string file = System.IO.Directory.GetFiles(HttpContext.Current.Server.MapPath(folderName), "*.txt");
FileInfo fi = new FileInfo(file);
// to read all content of this file you can use -
File.ReadAllLines(fi.FullName)
and after this you can use Dictionary to save your data and then you can use it later.
You can read here - http://csharp.net-informations.com/collection/dictionary.htm

Categories