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!
I've been working with some big delimited text (~1GB) files these days. It looks like somewhat below
COlumn1 #COlumn2#COlumn3#COlumn4
COlumn1#COlumn2#COlumn3 #COlumn4
where # is the delimiter.
In case a column is invalid I might have to remove it from the whole text file. The output file when Column 3 is invalid should look like this.
COlumn1 #COlumn2#COlumn4
COlumn1#COlumn2#COlumn4
string line = "COlumn1# COlumn2 #COlumn3# COlumn4";
int junk =3;
int columncount = line.Split(new char[] { '#' }, StringSplitOptions.None).Count();
//remove the [junk-1]th '#' and the value till [junk]th '#'
//"COlumn1# COlumn2 # COlumn4"
I's not able to find a c# version of this in SO. Is there a way I can do that? Please help.
EDIT:
The solution which I found myself is like below which does the job. Is there a way I could modify this to a better way so that it narrows down the performance impact it might have in case of large text files?
int junk = 3;
string line = "COlumn1#COlumn2#COlumn3#COlumn4";
int counter = 0;
int colcount = line.Split(new char[] { '#' }, StringSplitOptions.None).Length - 1;
string[] linearray = line.Split(new char[] { '#' }, StringSplitOptions.None);
List<string> linelist = linearray.ToList();
linelist.RemoveAt(junk - 1);
string finalline = string.Empty;
foreach (string s in linelist)
{
counter++;
finalline += s;
if (counter < colcount)
finalline += "#";
}
Console.WriteLine(finalline);
EDITED
This method can be very memory expensive, as your can read in this post, the suggestion should be:
If you need to run complex queries against the data in the file, the right thing to do is to load the data to database and let DBMS to take care of data retrieval and memory management.
To avoid memory consumption you should use a StreamReader to read file line by line
This could be a start for your task, missing your invalid match logic
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
const string fileName = "temp.txt";
var results = FindInvalidColumns(fileName);
using (var reader = File.OpenText(fileName))
{
while (!reader.EndOfStream)
{
var builder = new StringBuilder();
var line = reader.ReadLine();
if (line == null) continue;
var split = line.Split(new[] { "#" }, 0);
for (var i = 0; i < split.Length; i++)
if (!results.Contains(i))
builder.Append(split[i]);
using (var fs = new FileStream("new.txt", FileMode.Append, FileAccess.Write))
using (var sw = new StreamWriter(fs))
{
sw.WriteLine(builder.ToString());
}
}
}
}
private static List<int> FindInvalidColumns(string fileName)
{
var invalidColumnIndexes = new List<int>();
using (var reader = File.OpenText(fileName))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line == null) continue;
var split = line.Split(new[] { "#" }, 0);
for (var i = 0; i < split.Length; i++)
{
if (IsInvalid(split[i]) && !invalidColumnIndexes.Contains(i))
invalidColumnIndexes.Add(i);
}
}
}
return invalidColumnIndexes;
}
private static bool IsInvalid(string s)
{
return false;
}
}
}
First, what you will do is re-write the line to a text file using a 0-length string for COlumn3. Therefore the line after being written correctly would look like this:
COlumun1#COlumn2##COlumn4
As you can see, there are two delimiters between COlumn2 and COlumn4. This is a cell with no data in it. (By "cell" I mean one column of a certain, single row.) Later, when some other process reads this using the Split function, it will still create a new value for Column 3, but in the array generated by Split, the 3rd position would be an empty string:
String[] columns = stream_reader.ReadLine().Split('#');
int lengthOfThirdItem = columns[2].Length; // for proof
// lengthOfThirdItem = 0
This reduces invalid values to null and persists them back in the text file.
For more on String.Split see C# StreamReader save to Array with separator.
It is not possible to write to lines internal to a text file while it is also open for read. This article discusses it some (simultaneous read-write a file in C#), but it looks like that question-asker just wants to be able to write lines to the end. You want to be able to write lines at any point in the interior. I think this is not possible without buffering the data in some way.
The simplest way to buffer the data is rename the file to a temp file first (using File.CoMovepy() // http://msdn.microsoft.com/en-us/library/system.io.file.move(v=vs.110).aspx). Then use the temp file as the data source. Just open the temp file that to read in the data which may have corrupt entries, and write the data afresh to the original file name using the approach I describe above to represent empty columns. After this is complete, then you should delete the temp file.
Important
Deleting the temp file may leave you vulnerable to power and data transients (or software 'transients'). (I.e., a power drop that interrupts part of the process could leave the data in an unusable state.) So you may also want to leave the temp file on the drive as an emergency backup in case of some problem.
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]
}
}
I have a text file which contains following
Name address phone salary
Jack Boston 923-433-666 10000
all the fields are delimited by the spaces.
I am trying to write a C# program, this program should read a this text file and then store it in the formatted array.
My Array is as follows:
address
salary
When ever I am trying to look in google I get is how to read and write a text file in C#.
Thank you very much for your time.
You can use File.ReadAllLines method to load the file into an array. You can then use a for loop to loop through the lines, and the string type's Split method to separate each line into another array, and store the values in your formatted array.
Something like:
static void Main(string[] args)
{
var lines = File.ReadAllLines("filename.txt");
for (int i = 0; i < lines.Length; i++)
{
var fields = lines[i].Split(' ');
}
}
Do not reinvent the wheel. Can use for example fast csv reader where you can specify a delimeter you need.
There are plenty others on internet like that, just search and pick that one which fits your needs.
This answer assumes you don't know how much whitespace is between each string in a given line.
// Method to split a line into a string array separated by whitespace
private string[] Splitter(string input)
{
return Regex.Split(intput, #"\W+");
}
// Another code snippet to read the file and break the lines into arrays
// of strings and store the arrays in a list.
List<String[]> arrayList = new List<String[]>();
using (FileStream fStream = File.OpenRead(#"C:\SomeDirectory\SomeFile.txt"))
{
using(TextReader reader = new StreamReader(fStream))
{
string line = "";
while(!String.IsNullOrEmpty(line = reader.ReadLine()))
{
arrayList.Add(Splitter(line));
}
}
}
I have a .txt file with a list of 174 different strings. Each string has an unique identifier.
For example:
123|this data is variable|
456|this data is variable|
789|so is this|
etc..
I wish to write a programe in C# that will read the .txt file and display only one of the 174 strings if I specify the ID of the string I want. This is because in the file I have all the data is variable so only the ID can be used to pull the string. So instead of ending up with the example about I get just one line.
eg just
123|this data is variable|
I seem to be able to write a programe that will pull just the ID from the .txt file and not the entire string or a program that mearly reads the whole file and displays it. But am yet to wirte on that does exactly what I need. HELP!
Well the actual string i get out from the txt file has no '|' they were just in the example. An example of the real string would be: 0111111(0010101) where the data in the brackets is variable. The brackets dont exsist in the real string either.
namespace String_reader
{
class Program
{
static void Main(string[] args)
{
String filepath = #"C:\my file name here";
string line;
if(File.Exists(filepath))
{
StreamReader file = null;
try
{
file = new StreamReader(filepath);
while ((line = file.ReadLine()) !=null)
{
string regMatch = "ID number here"; //this is where it all falls apart.
Regex.IsMatch (line, regMatch);
Console.WriteLine (line);// When program is run it just displays the whole .txt file
}
}
}
finally{
if (file !=null)
file.Close();
}
}
Console.ReadLine();
}
}
}
Use a Regex. Something along the lines of Regex.Match("|"+inputString+"|",#"\|[ ]*\d+\|(.+?)\|").Groups[1].Value
Oh, I almost forgot; you'll need to substitute the d+ for the actual index you want. Right now, that'll just get you the first one.
The "|" before and after the input string makes sure both the index and the value are enclosed in a | for all elements, including the first and last. There's ways of doing a Regex without it, but IMHO they just make your regex more complicated, and less readable.
Assuming you have path and id.
Console.WriteLine(File.ReadAllLines(path).Where(l => l.StartsWith(id + "|")).FirstOrDefault());
Use ReadLines to get a string array of lines then string split on the |
You could use Regex.Split method
FileInfo info = new FileInfo("filename.txt");
String[] lines = info.OpenText().ReadToEnd().Split(' ');
foreach(String line in lines)
{
int id = Convert.ToInt32(line.Split('|')[0]);
string text = Convert.ToInt32(line.Split('|')[1]);
}
Read the data into a string
Split the string on "|"
Read the items 2 by 2: key:value,key:value,...
Add them to a dictionary
Now you can easily find your string with dictionary[key].
first load the hole file to a string.
then try this:
string s = "123|this data is variable| 456|this data is also variable| 789|so is this|";
int index = s.IndexOf("123", 0);
string temp = s.Substring(index,s.Length-index);
string[] splitStr = temp.Split('|');
Console.WriteLine(splitStr[1]);
hope this is what you are looking for.
private static IEnumerable<string> ReadLines(string fspec)
{
using (var reader = new StreamReader(new FileStream(fspec, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
while (!reader.EndOfStream)
yield return reader.ReadLine();
}
}
var dict = ReadLines("input.txt")
.Select(s =>
{
var split = s.Split("|".ToArray(), 2);
return new {Id = Int32.Parse(split[0]), Text = split[1]};
})
.ToDictionary(kv => kv.Id, kv => kv.Text);
Please note that with .NET 4.0 you don't need the ReadLines function, because there is ReadLines
You can now work with that as any dictionary:
Console.WriteLine(dict[12]);
Console.WriteLine(dict[999]);
No error handling here, please add your own
You can use Split method to divide the entire text into parts sepparated by '|'. Then all even elements will correspond to numbers odd elements - to strings.
StreamReader sr = new StreamReader(filename);
string text = sr.ReadToEnd();
string[] data = text.Split('|');
Then convert certain data elements to numbers and strings, i.e. int[] IDs and string[] Strs. Find the index of the given ID with idx = Array.FindIndex(IDs, ID.Equals) and the corresponding string will be Strs[idx]
List <int> IDs;
List <string> Strs;
for (int i = 0; i < data.Length - 1; i += 2)
{
IDs.Add(int.Parse(data[i]));
Strs.Add(data[i + 1]);
}
idx = Array.FindIndex(IDs, ID.Equals); // we get ID from input
answer = Strs[idx];