Read a Text File and Populate an Array - c#

I am to read a file and populate a String array. My data is like:
Accident.
An unplanned event, unexpected and undesigned, which occurs suddenly and at a definite place.
Accident Frequency.
The rate of the occurrence of accidents, often expressed in terms of the number of accidents over a period of time. It is one method used for measuring the effectiveness of loss prevention services. Contrast with Accident Severity.
Accident Prevention.
See Loss Prevention Service.
Accident Severity.
A measure of the severity or seriousness of losses, rather than the number of losses. It is measured in terms of time lost from work rather than the number of individual accidents. It is another way of measuring the effectiveness of loss prevention services. Contrast with Accident Frequency.
My code is:
private void openfile_Click(object sender, EventArgs e)
{
if (text.Text == String.Empty)
{
err.SetError(text, "Needs to contain Text");
}
DialogResult result = open_dialog.ShowDialog();
if (result == DialogResult.OK)
{
try
{
string file_name = open_dialog.FileName;
System.IO.StreamReader sr = new System.IO.StreamReader(file_name);
String line;
String[] wordslist=new String[count];
using (StreamReader reader = File.OpenText(file_name))
{
// read each line, ensuring not null (EOF)
while ((line = reader.ReadLine()) != null)
{
if (line == String.Empty)
{
}
else
{
wordslist = line.Split(' ');
count += 1;
}
}
}
for (int i=0;i<wordslist.Length;i++)
{
//if (str==(text.Text))
//{
//var index = Array.FindIndex(wordslist, row => row.Contains(text.Text));
Console.WriteLine("\ncapacity " + wordslist[i]);
//Console.WriteLine("\n" + wordslist[index - 1]+" capacity");
//}
}
}
catch (Exception ex)
{
Console.WriteLine("\n\nERROR= " + ex);
}
}
}
I simply want to print the contents of the array being populated with the file contents but the array is not being populated. But when I remove the Blank lines between my data the array will be populated with some few lines and I'm able to print some but not ALL contents.
The problem is that my data is so large that I can't remove lines and don't want to be! Is there any solution so that i can do this thing correctly?

You can use Linq
var wordslist= System.IO.File.ReadAllLines("filename")
.Where(x => !string.IsNullOrWhiteSpace(x))
.SelectMany(x => x.Split(' '));
foreach(var word in wordlist)
{
Console.WriteLine("\ncapacity " + word);
}

There is a combination of issues. Firstly this line;
String[] wordslist=new String[count];
That does nothing. It creates an array of length zero and sets the wordslist reference to that.
Then this is the real problem;
wordslist = line.Split(' ');
Split returns a new string array, it doesn't add to the current one. You only get the final line because wordslist gets set to the result of calling split on that line in the last iteration of the loop. You can fix your code by doing;
List<string> wordslist = new List<string>();
then doing;
wordslist.Add(line.Split(' '));
to add items. List<T> is a dynamic array and will grow as necessary. T[] (an array) cannot grow dynamically and because of that is not a good collection choice for reading the file.
Here's another suggestion (how I would do it);
string[] words = File.ReadAllLines(path).Where(x => !x.IsNullOrEmpty())
.Select(x => x.Split(' '))
.SelectMany();
That one liner will first, read every line of the file into a string[], the Where is then applied and all of the empty lines are removed. After that each line is split on space which gives you an IEnumerable<string[]> (a list of string arrays where each array is a lines worth of words) and finally the SelectMany "flattens" the list meaning it combines all of those arrays into one.

private void openfile_Click(object sender, EventArgs e) {
if (text.Text == String.Empty) {
err.SetError(text, "Needs to contain Text");
}
DialogResult result = open_dialog.ShowDialog();
if (result == DialogResult.OK)
{
try
{
string file_name = open_dialog.FileName;
System.IO.StreamReader sr = new System.IO.StreamReader(file_name);
String line;
List<string> wordslist=new List<string>(count);
using (StreamReader reader = File.OpenText(file_name))
{
// read each line, ensuring not null (EOF)
while ((line = reader.ReadLine()) != null)
{
if (line != String.Empty) {
// Here instead of replacing array with new content
// we add new words to already existing list of strings
wordslist.AddRange(line.Split(' '));
count += 1;
}
}
}
// Count instead of Length because we're using List<T> now
for (int i=0;i<wordslist.Count;i++)
{
Console.WriteLine("\ncapacity " + wordslist[i]);
}
}
catch (Exception ex)
{
Console.WriteLine("\n\nERROR= " + ex);
}
}
}

I am not sure if I understand what you ask for, but it appears you want to read content of file without empty lines?
Your code is quite a mess, here you got little bit that will return all non-empty lines from file.
List<string> readIt(string fileName)
{
string line;
List<string> data = new List<string>();
StreamReader file = new StreamReader(fileName);
while((line = file.ReadLine()) != null)
{ if (line!="") data.Add(line); }
file.Close();
return data;
}

Related

How to delete all lines in text file that is NOT a number greater than a specific value? (Including strings)

My Issue:
I am looking into a text file and i need to delete all the lines, or use string.empty that does not meet the requirement. For example,
The requirement is 50000. There are words/text in the file and also numbers that are smaller than the requirement. How can i delete all line in a text file that do not meet the requirement? I do not want to be specific with the other values in the text file as they can differ.
My Research:
I have searched and found to delete specific values then rewrite them onto a new file which i am trying to do. I have found different ways that dont meet my needs. I am using what i have found below but am missing something to make it complete
My Effort:
DialogResult openFile = openFileDialog1.ShowDialog();
if (openFile == DialogResult.OK)
{
string file = openFileDialog1.FileName;
string content = File.ReadAllText(file);
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Text File|*.txt";
sfd.FileName = "New Text Doucment";
sfd.Title = "Save As Text File";
if (sfd.ShowDialog() == DialogResult.OK)
{
string path = sfd.FileName;
StreamWriter bw = new StreamWriter(File.Create(path));
bw.WriteLine(content);
bw.Close();
File.WriteAllLines(path, File.ReadAllLines(path).Select(x => string.Format("{0},", x)));
string newContent = File.ReadAllText(path);
newContent = newContent.Remove(newContent.LastIndexOf(","));
File.WriteAllText(path, newContent);
string secondContent = File.ReadAllText(path);
int number = int.Parse(File.ReadAllText(path));
if (checkBox1.Checked == true)
{
secondContent = secondContent.Replace("BRUSH(1,0)", string.Empty);
secondContent = secondContent.Replace("REGION 1,", string.Empty);
secondContent = secondContent.Remove(secondContent.LastIndexOf(","));
File.WriteAllText(path, secondContent);
if (secondContent.Contains())
{
number = 0;
secondContent = secondContent.Replace(number.ToString(), string.Empty);
File.WriteAllText(path, secondContent);
}
}
else if (checkBox2.Checked == true)
{
secondContent = secondContent.Replace("BRUSH(1,0),", ")),");
secondContent = secondContent.Replace("REGION 1,", string.Empty);
secondContent = secondContent.Remove(secondContent.LastIndexOf(","));
File.WriteAllText(path, secondContent);
}
//Just trying
foreach (char c in secondContent)
{
if (secondContent.All(char.IsDigit))
{
char = string.Empty;
}
}
}
}
What i am doing above:
Grabbing an existing file,
adding the contents to a new file,
add a comma at the end of each line,
removing the last comma at the end of the file.
removing a line that contains brush or region
Now here are examples of the file:
TYPE_CODE char(2),
DESCRIPT0 char(25),
TYPE_COD0 char(3),
DESCRIPT1 char(36),
DATA,
BRUSH(1,0),
REGION(1,0),
13502,
319621.99946835 110837.002493295,
319640.501385461 110850.59860145,
319695.199120806 110879.700271183,
319728.303041127 110879.300385649,
319752.898058391 110876.501186912,
319767.401120868 110872.702274339,
The numbers at the bottom of that example is what the entire document should look like
To address just the issue stated try the following:
//Get the lines from the file
List<string> lines = System.IO.File.ReadAllLines("MyFile.txt").ToList();
//Removed the lines which are empty or when split using ' ' contain items other the numbers >= 50000
double d = 0;
lines.RemoveAll(x => string.IsNullOrWhiteSpace(x) || x.TrimEnd(',').Split(' ').Any(y => !double.TryParse(y, out d) || double.Parse(y) < 50000));
//Write the new file
System.IO.File.WriteAllLines("MyFile2.txt", lines.ToArray());
To add a comma to the end of each line add the following lines before saving:
//Remove any existing ',' and add our own
lines = lines.Select(x => x.TrimEnd(',') + ",").ToList();
//Remove any trailing ',' from the last line
lines[lines.Count - 1] = lines[lines.Count - 1].TrimEnd(',');
(Edited to handle multiple numbers per line)
(Fixed conversion errors)
(Fixed for existing ',')
First, abstraction would be your friend here. Break up your code into different peices to make it a little easier to handle. Plus when you have to change your requirements later, you will have an easy spot to do it.
Second, File.ReadLines is also your friend because it will give you a collection of strings, which will let you use LINQ.
Which brings me to your third friend, LINQ, which will let you query the collection of file lines.
public void FormatFile(string sourcePath, string targetPath)
{
IEnumerable<String> originalContent = GetFileLines(sourcePath);
IEnumerable<String> formatedContent = ProcessFileLines(originalContent);
OutputResults(targetPath, formatedContent);
}
public IEnumerable<String> GetFileLines(string path) {
return File.ReadLines(path);
}
public IEnumerable<string> ProcessFileLines(IEnumerable<string> fileLines)
{
// In this method you can process the logic that applies to the whole
// set of file lines (e.g. lineCount, removing empyLines, etc)
return processedLines.Select(l => ProcessLine(l)
.Where(l => !string.IsNullOrEmpty(l))
.GetRange(0, MAX_LINE_COUNT);
}
public string ProcessLine(string fileLine)
{
// In this method just focus on logic applied to each specific line.
string s = fileLine.Substring(0, 5);
if (s.Equals("BRUSH", StringComparison.InvariantCultureIgnoreCase)
return string.Empty;
return fileLine;
}
public void OutputResults(string targetPath, IEnumerable<string> fileLines)
{
string outputText = fileLines.Join($",{Environment.NewLine}");
File.WriteAllText(targetPath, outputText);
}
So basically you can just call FormatFile(#"C:\mySource", #"C:\myTarget"); and you will be good to go.

Read file, check correctness of column, write file C#

I need to check certain columns of data to make sure there are no trailing blank spaces. At first thought I thought it would be very easy, but after attempting to achieve the goal I have got stuck.
I know that there should be 6-digits in the column I need to check. If there is less I will reject, if there are more I will trim the blank spaces. After doing that for the entire file, I want to write it back to the file with the same delimiters.
This is my attempt:
Everything seems to be working correctly except for writing the file.
if (File.Exists(filename))
{
using (StreamReader sr = new StreamReader(filename))
{
string lines = sr.ReadLine();
string[] delimit = lines.Split('|');
while (delimit[count] != "COLUMN_DATA_TO_CHANGE")
{
count++;
}
string[] allLines = File.ReadAllLines(#filename);
foreach(string nextLine in allLines.Skip(1)){
string[] tempLine = nextLine.Split('|');
if (tempLine[count].Length == 6)
{
checkColumn(tempLine);
writeFile(tempLine);
}
else if (tempLine[count].Length > 6)
{
tempLine[count] = tempLine[count].Trim();
checkColumn(tempLine);
}
else
{
throw new Exception("Not enough numbers");
}
}
}
}
}
public static void checkColumn(string[] str)
{
for (int i = 0; i < str[count].Length; i++)
{
char[] c = str[count].ToCharArray();
if (!Char.IsDigit(c[i]))
{
throw new Exception("A non-digit is contained in data");
}
}
}
public static void writeFile(string[] str)
{
string temp;
using (StreamWriter sw = new StreamWriter(filename+ "_tmp", false))
{
StringBuilder builder = new StringBuilder();
bool firstColumn = true;
foreach (string value in str)
{
if (!firstColumn)
{
builder.Append('|');
}
if (value.IndexOfAny(new char[] { '"', ',' }) != -1)
{
builder.AppendFormat("\"{0}\"", value.Replace("\"", "\"\""));
}
else
{
builder.Append(value);
}
firstColumn = false;
}
temp = builder.ToString();
sw.WriteLine(temp);
}
}
If there is a better way to go about this, I would love to hear it. Thank you for looking at the question.
edit:
file structure-
country| firstname| lastname| uniqueID (column I am checking)| address| etc
USA|John|Doe|123456 |5 main street|
notice the blank space after the 6
var oldLines = File.ReadAllLines(filePath):
var newLines = oldLines.Select(FixLine).ToArray();
File.WriteAllLines(filePath, newLines);
string FixLine(string oldLine)
{
string fixedLine = ....
return fixedLine;
}
The main problem with writing the file is that you're opening the output file for each output line, and you're opening it with append=false, which causes the file to be overwritten every time. A better approach would be to open the output file one time (probably right after validating the input file header).
Another problem is that you're opening the input file a second time with .ReadAllLines(). It would be better to read the existing file one line at a time in a loop.
Consider this modification:
using (StreamWriter sw = new StreamWriter(filename+ "_tmp", false))
{
string nextLine;
while ((nextLine = sr.ReadLine()) != null)
{
string[] tempLine = nextLine.Split('|');
...
writeFile(sw, tempLine);

Parsing CSV data

I am trying to parse a CSV file with data with no luck, i have tried a bunch of tools online and none has been able to parse the CSV file correctly. I am baffled by the fact that i am in here asking for help as one would think parsing CSV data would be something super easy.
The format of the CSV data is like this:
",95,54070,3635,""Test Reservation"",0,102,0.00,0.00,2014-12-31,""Name of customer"",""$12.34 + $10, special price"",""extra information"",,CustomerName,,,,,1234567890,youremail#domain.com,CustomerName,2014-12-31,23:59:59,16,0,60,2,120,0,NULL,NULL,NULL,"
Current code:
private void btnOpenFileDialog_Click(object sender, EventArgs e)
{
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
using (StreamReader reader = new StreamReader(openFileDialog1.FileName))
{
string line;
while ((line = reader.ReadLine()) != null)
{
ParseCsvLine(line);
}
}
}
}
private void ParseCsvLine(string line)
{
if (line != string.Empty)
{
string[] result;
using (var csvParser = new TextFieldParser(new StringReader(line)))
{
csvParser.Delimiters = new string[] { "," };
result = csvParser.ReadFields();
}
foreach (var item in result)
{
Console.WriteLine(item + Environment.NewLine);
}
}
}
The result variable only has one item and its:
,95,54070,3635,"Test Reservation",0,102,0.00,0.00,2014-12-31,"Name of customer","$12.34 + $10, special price","extra information",,CustomerName,,,,,1234567890,youremail#domain.com,CustomerName,2014-12-31,23:59:59,16,0,60,2,120,0,NULL,NULL,NULL,
// Add Microsoft.VisualBasic.dll to References.
using Microsoft.VisualBasic.FileIO;
// input is your original line from csv.
// Remove starting and ending quotes.
input = input.Remove(0, 1);
input = input.Remove(input.Length - 1);
// Replace double quotes with single quotes.
input = input.Replace("\"\"", "\"");
string[] result;
using (var csvParser = new TextFieldParser(new StringReader(input)))
{
csvParser.Delimiters = new string[] { "," };
result = csvParser.ReadFields();
}
You can check out a previous post that deals with those pesky commas in csv files. I'm linking it here.
Also Mihai, your solution works well for just the one line but will fail once there are many lines to parse.

Extract data from text file

I need to extract some data from a text file and insert to columns in excel sheet. I know how to do this if the rows and the length of the string is known.
try
{
using (System.IO.StreamReader sr = new System.IO.StreamReader("test.txt")
{
string line;
while ((line = sr.ReadLine()) != null)
{
listSNR.Items.Add(line.Substring (78,4));
}
}
}
But the particular text file is complex and the starting index or the length cannot be provided. But the starting word (PCPU01) of the row is known.
Eg: PCPU01,T2716,0.00,0.01,0.00,0.00
output:
T2716 0 0.01 0 0
In that case can somebody please let me know how to extract the texts?
using(System.IO.StreamReader sr = new System.IO.StreamReader("test.txt"))
{
string line;
while((line = sr.ReadLine()) != null)
{
string[] split = line.Split(',');
//...
}
}
split[0] will return "PCPU01", split[1] "T2716" and so on.
You can split one string into an array of strings, separated by a given character. This way, you could split the source string by a comma and use the resulting strings to build your output. Example:
string source = "PCPU01,T2716,0.00,0.01,0.00,0.00";
string[] parts = source.Split(',');
StringBuilder result = new StringBuilder();
result.Append(parts[1]); // The second element in the array, i.e. T2716
result.Append(" ");
result.Append(parts[2]); // 0.00
... // And so on...
return result.ToString() // return a string, not a StringBuilder
I hope this helps a little bit. You might have to tweak it to your needs. But this is a higher level code that gives you general idea of extracting data off a notepad.
DialogResult result = openFileDialog.ShowDialog();
Collection<Info> _infoCollection = new Collection<Info>();
Collection<string> listOfSubDomains = new Collection<string>();
string[] row;
string line;
// READ THE FILE AND STORE IT IN INFO OBJECT AND STORE TAHT INFO OBJECT IN COLLECTION
try
{
using (StreamReader reader = new StreamReader(openFileDialog.FileName))
{
while((line = reader.ReadLine()) != null)
{
Info _info = new Info();
row = line.Split(' ');
_info.FirstName = row[0];
_info.LastName = row[1];
_info.Email = row[2];
_info.Id = Convert.ToInt32(row[3]);
_infoCollection.Add(_info);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
thanks for the answers. What i wanted is to identify the particular line in the text file and split the line into columns. So i was able to do this by calling a GetLine method:
string line15=GetLine(#"test.txt",15);
public string GetLine(string fileName, int line)
{
using (System.IO.StreamReader ssr = new System.IO.StreamReader("test.txt"))
//using (var ssr = new StreamReader("test.txt"))
{
for (int i = 1; i < line; i++)
ssr.ReadLine();
return ssr.ReadLine();
}
}
Then i splitted this line by using the delimiter (,)
This was my approach in C#. It takes a string input (which you can get out of a text file) and an int with which line you want to get. It then separates the string at a given seperator char to a list which in turn is then read out. If the given line number is lower than the count of the created list, the entry is given back.
public string GetLine(string multiline,int line)
{
List<string> lines = new List<string>();
lines = multiline.Split('\n').ToList<string>();
return lines.Count >= line ? lines[line] : "";
}

How to use textfieldParser to edit a CSV file?

I wrote a small function that reads a csv file using textField line by line , edit it a specific field then write it back to a CSV file.
Here is the code :
private void button2_Click(object sender, EventArgs e)
{
String path = #"C:\file.csv";
String dpath = #"C:\file_processed.csv";
List<String> lines = new List<String>();
if (File.Exists(path))
{
using (TextFieldParser parser = new TextFieldParser(path))
{
String line;
parser.HasFieldsEnclosedInQuotes = true;
parser.Delimiters = new string[] { "," };
while ((line = parser.ReadLine()) != null)
{
string[] parts = parser.ReadFields();
if (parts == null)
{
break;
}
if ((parts[12] != "") && (parts[12] != "0"))
{
parts[12] = parts[12].Substring(0, 3);
//MessageBox.Show(parts[12]);
}
lines.Add(line);
}
}
using (StreamWriter writer = new StreamWriter(dpath, false))
{
foreach (String line in lines)
writer.WriteLine(line);
}
MessageBox.Show("CSV file successfully processed ! ");
}
}
The field I want to edit is the 12th one (parts[12]):
for example : if parts[12] = 000,000,234 then change to 000
the file is created the problem is it does not edit the file and half the records are missing. I am hoping someone could point the mistake.
You call both parser.ReadFields() and parser.ReadLine(). Each of them advance the cursor by one. That's why you're missing half the rows. Change the while to:
while(!parser.EndOfData)
Then add parts = parser.ReadFields(); to the end of the loop. Not having this is why you're edit isn't being seen.
You can also remove:
if (parts == null)
{
break;
}
Since you no longer have line, you'll need to use the fields to keep track of your results:
lines.Add(string.Join(",", parts));//handle string escaping fields if needed.

Categories

Resources