Unable to split strings, and confusing ";" requirements - c#

Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
namespace DataAnalysis
{
class Data
{
public int InTime;
public string InLocation;
public bool Direction;
public int LOS_F;
// create a Data object from a CSV format string.
static Data FromString(string line)
{
var fields = line.split(",");
return new Data
{
InTime = TimeSpan.Parse(fields[3]),
InLocation = fields[5],
Direction = fields[5][0], // to get the direction E/N/S/W
LOS_F = float.Parse(fields[16])
};
}
}
class Program
{
string[] directions = new string[] { "E", "N", "S", "W" };
static void Main(string[] args)
{
var path = #"C:\Documents and Settings\Siva-Admin\Desktop\5.5 Capacity Models\";
// ^--- No need to escape the backslashes
var subdirs = Directory.GetDirectories(path);
// The subdirs variable contains the FULL paths
foreach (string subdir in subdirs)
{
List<List<float>> allAvgs = new List<List<float>>();
using (StreamWriter compiled = new StreamWriter(
Path.Combine(subdir, "compiledresults.csv")))
{
compiled.Write("heading,EastAvg,NorthAvg,SouthAvg,WestAvg");
for (int i = 1; i <= 10; i++)
{
List<Data> info = new List<Data>();
using (StreamReader reader = new StreamReader(
Path.Combine(subdir, "results" + i.ToString() + #"\JourneyTimes.csv")))
{
// Read the header line first!
string line = reader.ReadLine();
while ((line = reader.ReadLine()) != null)
info.Add(Data.FromString(line));
}
List<float> avgs = new List<float>();
for (string dir in directions)
{
List<Data> perDirection = info.Where(d => d.Direction = dir) as List<Data>;
float sum = perDirection.Sum(d => d.LOS_F);
float average = sum / perDirection.Count();
avgs.Add(average);
}
allAvgs.Add(avgs);
compiled.Write("results" + i.ToString() + "," + string.Join(",", avgs) + "\n");
}
compiled.Write("scenario_average");
for (int j = 1; j <= 4; j++)
{
compiled.Write("," + allAvgs.Sum(d => d[0]) / allAvgs.Count());
}
}
}
}
}
}
I get the following errors:
Error 1; expected(Line 67, "for (string dir in directions)" )
Error 2; expected(LINE 67, " " )
Error 3 'string' does not contain a definition for 'split' and no extension method 'split' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) (LINE 20, var fields = line.split (","); )
I do not understand the need for the ; as these are arguments being passed are they not? I also do not understand why I cannot split a string.

Error 1 and 2: Your for loop should be a foreach loop:
foreach (string dir in directions)
Error 3: the S in split should be upper case:
var fields = line.Split(',');

for (string dir in directions) should be foreach (string dir in directions)
EDIT to add:
Addtionally, here:
List<Data> perDirection = info.Where(d => d.Direction = dir) as List<Data>;
You seem to be making an assignment instead of a equality check, i.e
d.Direction = dir should be d.Direction == dir
However, it still won't work since you are comparing a string to a bool.

You need to replace line.split(",") with line.Split(',') (note the uppercase S).
(also replace for with foreach in line 67 as others have pointed out).

Error1 & Error2 use foreach instead of for;
Erorr3 it's Split instead of split.

Related

C# separation to tab separation

How do I change the space separation to tab separation.
Because [ LD Port 02 CSTID F7SC67: Sorts Complete. ] has a lot of space separation.
So I can’t split through Split !
List<string> add_list = new List<string>();
List<string> ok_list = new List<string>();
IEnumerable<String> lines = File.ReadLines("C:\\Users\\USER\\Downloads\\1231231231.log");
foreach (string line in lines)
{
add_list.Add(line);
}
foreach (string row in add_list)
{
var data = row.Split(' ');
Console.WriteLine(data);
}
Edit (by #chase): OP does not want to split by just spaces - this is why their code is wrong. Their final outcome should be the one mentioned in What I want: - where each item is separated by a comma and each item is clearly distinct. The input to reach this outcome is mentioned in Data:
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication4
{
class Program
{
const string FILENAME = #"c:\temp\test.txt";
static void Main(string[] args)
{
List<List<string>> data = GetFixedWidth(FILENAME);
}
static List<List<string>> GetFixedWidth(string filename)
{
int[] startPosition = { 0, 6, 15, 24 };
StreamReader reader = new StreamReader(filename);
string line = "";
int length = 0;
List<List<string>> data = new List<List<string>>();
while ((line = reader.ReadLine()) != null)
{
line = line.Trim();
if(line.Length > 0)
{
List<string> rowList = new List<string>();
data.Add(rowList);
for (int i = 0; i < startPosition.Length; i++)
{
if (line.Length > startPosition[i])
{
if (i == startPosition.Length - 1)
{
string lastColumn = line.Substring(startPosition[i]);
if (lastColumn.Contains(":"))
{
string[] splitData = line.Substring(startPosition[i]).Split(new char[] { ':' });
foreach (string split in splitData)
{
rowList.Add(split.Trim());
}
}
else
{
rowList.Add(lastColumn);
}
}
else
{
length = startPosition[i + 1] - startPosition[i];
rowList.Add(line.Substring(startPosition[i], length).Trim());
}
}
}
}
}
return data;
}
}
}

C# Add a blank value in between string in of CSV file

I have this on a string that is generated from a list how can I add a blank value in between the string.
using (var file = File.CreateText()
{
foreach (var permutation in result)
{
file.WriteLine(string.Join(",", permutation));
//i++;
}
}
Here is the result:
string result = A,B,C,D,E,F,G,H,I,J
How can I add a blank value ", ," in the result at a specific index
Example: A,B,C,D,E,F, ,G,H,I,J
Note: result is a permutation and length is not consistent
Result is a IEnumerable can it be split?
You can split your string with the comma as the separator, go through your characters and add them to a list. Add an extra empty string at your desired index and join the data back together. This way you don't have to deal with deciding if you need to add a commar or not when concatenating the strings.
var index = 6;
var data = "A,B,C,D,E,F,G,H,I,J";
var chars = data.Split(new [] { ',' });
List<string> resultData = new List<string>();
var i = 0;
foreach (var c in chars) {
if (i == index) {
resultData.Add(" ");
}
i++;
resultData.Add(c);
}
var result = string.Join(",", resultData.ToArray();
You can use the following basic algorithm to follow your questions code logic:
using (var file = File.CreateText())
{
int i = -1;// Loop counter
int termReplacementIndex = 3;// Input or constant to find letter to replace
foreach (var permutation in result)
{
i++;
if (i == ((termReplacementIndex * 2) - 2))// Only stops on letters not commas
{
file.WriteLine(string.Join(",", " ,"));// Adding of blank " "
}
file.WriteLine(string.Join(",", permutation));// Adding of letter
}
}
If permutation is a list you can just insert a null value at the required index:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var list = new List<string>();
list.Add("test 1");
list.Add("test 2");
list.Add("test 3");
list.Insert(2, null);
var str = string.Join(",", list);
Console.WriteLine(str); // test 1,test 2,,test 3
}
}
Modify the Collection before joining it so you wont have to split it and iterate it again.
As the side of permutation vary you could be trying to insert at index X when X is larger greater permutation.Count() instead of an ArgumentOutOfRangeException I decide to add the element at the end. But you will have to define that.
public string CsvProjection(List<string> inputs, int needleIndex, string needleValue)
{
if (needleIndex < 0)
{
throw new ArgumentOutOfRangeException("needleIndex must be positive.");
}
if (needleIndex > inputs.Count())
{//Either throw an exception because out of bound or add to the end
inputs.Add(needleValue);
}
inputs.Insert(needleIndex, needleValue);
return string.Join(",", inputs);
}
Usage simply add the value and the index variable:
var needleIndex= 2;
var needleValue = "My New Value";
using (var file = File.CreateText()
{
foreach (var permutation in result)
{
file.WriteLine(CsvProjection(permutation, needleIndex, needleValue));
}
}

How can I split a text File and use the Integers?

I have a text file that displays students names and their scores. The format looks like this:
James Johnson, 85
Robert Jones, 90
Lindsey Parks, 98
etc.
I have 10 names and scores all in the above format. My problem is how do I split the text file by the delimiter, and use the integers from the text file
Here is my code so far:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.FileIO;
namespace TextFiles1
{
class Program
{
static void Main(string[] args)
{
StreamReader sr = new StreamReader(#"C:\Users\jonda\Desktop\StudentScores.txt.txt");
string data = sr.ReadLine();
while (data != null)
{
Console.WriteLine(data);
string[] names = data.Split(',');
data = sr.ReadLine();
}
int total = 0;
double average = 0;
for (int index = 0; index < data.Length; index++)
{
total = total + data[index];
}
average = (double)total / data.Length;
Console.WriteLine("Average = " + average.ToString("N2"));
int high = data[0];
for (int index = 0; index < data.Length; index++)
{
if (data[index] > high)
{
high = data[index];
}
}
Console.WriteLine("Highest Score =" + high);
sr.Close();
Console.ReadLine();
}
}
}
First of all, it's a good idea to separate file operations and other operations. File operations are slow and costly, and should be completed as soon as possible. I would use a separate method, read the lines into a List and close the file operation first.
private static List<string> ReadFile(string path)
{
List<string> records = new List<string>();
using (StreamReader sr = new StreamReader(path))
{
while (!sr.EndOfStream)
records.Add(sr.ReadLine());
}
return records;
}
Then I would pass that list to another function and calculate average, max etc.
private static void CalculateAverage(List<string> lines)
{
char[] seperator = new char[] { ',' };
List<int> scores = new List<int>();
if (lines != null && lines.Count > 0)
{
foreach (string line in lines)
{
Console.WriteLine(line);
string[] parts = line.Split(seperator);
int val;
if (int.TryParse(parts[1], out val))
scores.Add(val);
}
}
Console.WriteLine("Average: {0}", scores.Average());
Console.WriteLine("Highest Score: {0}", scores.Max());
}
Then in your main program call the methods like this:
List<string> lines = ReadFile(path);
CalculateAverage(lines);
Use Regex to find each person info and then split each of them and extract Name and Score.
Try like this:
var inputStr = "James Johnson, 85 Robert Jones, 90 Lindsey Parks, 98";
var regex = new Regex(#"[A-z]* [A-z]*, [0-9]*");
return regex.Matches(inputStr)
.OfType<Match>()
.Select(p => p.Value.Split(','))
.Select(p => new { Name = p[0], Score = Convert.ToInt32(p[1].Trim()) });
Result :
I hope to be helpful for you :)

C# Dictionary doesn't find the key after being added

I've made a simple program that will read functions in a text file splitted by a new line and execute it just like a programming language. Here's the code:
using System;
using System.IO;
using System.Text;
using System.Linq;
using System.Threading;
using System.Collections.Generic;
namespace My_Project
{
class Program
{
public static Dictionary<string, string> variables = new Dictionary<string, string>();
static void Main(string[] args)
{
//string code = args[0];
string code = File.ReadAllText(#"TEXT FILE LOCATION HERE");
var lines = code.Split('\n');
foreach (string line in lines)
{
char[] lineInCharArray = line.ToCharArray();
if (lineInCharArray[0] == '-')
{
string variablename = (lineInCharArray[1]).ToString();
string value = line.Replace("-" + variablename, "");
Console.WriteLine("VARIABLE DEFINED: " + variablename + " - " + value);
variables.Add(variablename, value);
}
if (lineInCharArray[0] == '*')
{
if (lineInCharArray[1] == '*')
{
try
{
string requestedVariable = line.Replace("**", "");
Console.WriteLine("REQUESTED VARIABLE: " +
requestedVariable);
string printedValue = variables[requestedVariable];
Console.WriteLine(printedValue);
}
catch
{
Console.WriteLine("ERROR: ");
List<string> hhh = variables.Keys.ToList();
foreach (string item in hhh)
{
Console.WriteLine("--: " + item);
}
}
}
else
{
string printedValue = line.Replace("*", "");
Console.WriteLine(printedValue);
}
}
if (lineInCharArray[0] == '+')
{
string variable = variables[lineInCharArray[1].ToString()];
Int32 variableInInt = Convert.ToInt32(variable);
Int32 incrementation = Convert.ToInt32(line.Replace("+" + variable, ""));
for (int i = 0; i < incrementation + 1; i++)
{
variableInInt++;
}
variables[lineInCharArray[1].ToString()] = variableInInt.ToString();
}
}
Console.ReadLine();
}
}
}
Input (text file)
-a12 // Set a variable named 'a' and set the value to 12
-j8 // Set a variable named 'j' and set the value to 8
**j // Print the value of the variable of 'j'
**a // Print the value of the variable of 'a'
Problem:
The code outputs the following:
VARIABLE DEFINED: a - 12
VARIABLE DEFINED: j - 8
REQUESTED VARIABLE: j
ERROR:
--: a
--: j
REQUESTED VARIABLE: a
12
The code successfully assigned a to 12 and j to 8, but fails to print j (a is fine though). It says that the key j wasn't found on the dictionary even though the program did add j. The solution should output the following:
VARIABLE DEFINED: a - 12
VARIABLE DEFINED: j - 8
REQUESTED VARIABLE: j
8
REQUESTED VARIABLE: a
12
After the question I asked in a comment, and the answer you posted in a comment, it is obvious that what you have is a line feed character (\r) at the end of j, so what appears to be "j" is not exactly "j"; instead, it is "j\r".
So, you need to clean each line that you read from your file from control characters. In fact, you should clean them from any character which is not part of a valid identifier.

C# Check EOF in text file to fix array

I have a code to read text file and save the data into a double array to plot graph:
string filename = openFileDialog1.FileName;
var lineCount = 0;
using (var reader = File.OpenText(#filename))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var data = line.Split(',');
GlobalDataClass.dDataArray[lineCount, 0] = double.Parse(data[0]);
GlobalDataClass.dDataArray[lineCount, 1] = double.Parse(data[1]);
lineCount++;
}
ShowGraphData(lineCount);
}
And I have created a public class that initiate the array to [2000,2]:
static class GlobalDataClass
{
public static double[,] dDataArray = new double[2000, 2];
public static long iTotalReadingPoint;
}
My text file will be like:
0,29
1,31
2,32
3,32
4,30
However I want my program to detect the EOF so that the text file can contain random rows and still able to plot the graph not restricted to 2000 rows. Is it possible?please advice.TQ
If you want to use same class then try given code. This is not most optimum memory usage wise but still this should work.
string filename = openFileDialog1.FileName;
var lineCount = 0;
while ((line = reader.ReadLine()) != null)
{
if (GlobalDataClass.dDataArray.GetLength(0) == lineCount)
{
double[,] newTemp = GlobalDataClass.dDataArray;
int increaseLenght = newTemp.Length + 1000;
GlobalDataClass.dDataArray = new double[increaseLenght, 2];
Array.Copy(newTemp, GlobalDataClass.dDataArray, newTemp.LongLength);
}
var data = line.Split(',');
GlobalDataClass.dDataArray[lineCount, 0] = double.Parse(data[0]);
GlobalDataClass.dDataArray[lineCount, 1] = double.Parse(data[1]);
lineCount++;
}
The StreamReader class has a boolean property named EndOfStream that is essentially EoF for FileStream objects, and there's the Peek() method which is usually the standard way of reading until EoF.
var reader = File.OpenText( ... );
while( reader.Peek() != -1 ) //Peek() returns -1 on EoF or if the stream is not seekable.
{
var line = reader.ReadLine();
...
}
However reading from the file isn't really the problem if you don't want to be restricted to 2,000 lines. You might consider using a generic container of some flavour. For example:
using System.Collections.Generic;
string line = "12,34";
var dDataList = new List<KeyValuePair<double, double>>();
string[] parts = line.Split( ',' );
dDataList.Add( new KeyValuePair<double, double>( Double.Parse( parts[0] ), Double.Parse( parts[1] ) ) );
...
foreach( var pair in dDataList )
Console.WriteLine( "{0} => {1}", pair.Key, pair.Value ); // 12 => 34
Will let you add as many pairs of doubles as you want, within reason, without having to fiddle with array resizing/copying or any of that nasty business. It's generally considered good practice to use a container like List<T> when dealing with an unknown amount of data, and to use arrays when you know exactly how much data you're going to have or the absolute maximum amount of data you can have.
I think you're asking your question a bit wrong; The problem you have is that you are declaring an array of 2000 unit fixed length, but you actually want it to be dynamic length. As Abhinav said, a list may work for you:
firstly, you might consider creating a class/struct for your coordinates:
public class Coordinate
{
public double x;
public double y;
}
Then, create a list of coordinates (of 0 length initially)...
static class GlobalDataClass
{
public static List<Coordinate> dDataArray = new List<Coordinate>();
public static long iTotalReadingPoint;
}
And then add Coordinate objects to your list as you find new lines..
string filename = openFileDialog1.FileName;
var lineCount = 0;
using (var reader = File.OpenText(#filename))
{
string line;
while ((line = reader.ReadLine()) != null)
{
var data = line.Split(',');
Coordinate coord = new Coordinate();
coord.x = double.Parse(data[0]);
coord.y = double.Parse(data[1]);
GlobalDataClass.dDataArray.Add(coord);
lineCount++;
}
ShowGraphData(lineCount);
}

Categories

Resources