C# streamreader if questions - c#

I'm trying to write out the specific line of code that contains the IF statement. What appears to be happening if it never finds the code i'm looking to call in my if statement and i know it exists, it's a copy and paste. Also, how do i only write out the specific line that meets the if statement. Is there one where i should do a foreach? foreach (redsplitline in redsplitlines)
heres the code:
{
string linesplitnew = "ENDOB";
string[] redsplitlines = rdrred.ReadToEnd().Split(new string[] { linesplitnew }, StringSplitOptions.None);
string redpullline = "*BEGINOB\r\n6*";
string redpullline2 = "*BEGINOB\r\n13*";
if(redsplitlines.Contains(redpullline))
{
Console.WriteLine(redsplitlines);
}
else if(redsplitlines.Contains(redpullline2))
{
Console.WriteLine(redsplitlines);
}
}

Try this:
var lines = from line in redsplitlines
where line.Contains(redpullline) || line.Contains(redpullline2)
select line;
foreach (var l in lines)
Console.WriteLine(l);

Related

Retrieve Distinct Values From NotePad Elements

I've a notepad file that has the following format:
at-2017#yahoo.com
at-2017#yahoo.com
at-2018#yahoo.com
at-2018#yahoo.com
I require the following distinct output:
at-2017#yahoo.com
at-2018#yahoo.com
Tried the following code but it doesn't get distinct values:
List<string> lst = new List<string>();
foreach (string line in File.ReadLines(values))
{
line.Distinct().ToString();
lst.Add(line);
}
I know, this may seem stupid and guessing, missed something here.
First you should read all the lines and then get the distinct lines:
var allLines = File.ReadLines(values);
var distinctLines = allLines.Distinct();
foreach(var distinctLine in distinctLines)
{
Console.WriteLine(distinctLine);
}
Distinct() operates on a collection of elements, so you don't need to use it inside the loop.
Try following:
var lst = File.ReadLines(values).Distinct();
foreach (string line in lst)
{
Console.WriteLine(line) ;
}

How to skip some empty rows in csv file and continue reading rows with data? c# console application

I do have have 5 column within my CVS file, the first two columns have 3 empty rows. I would like to skip these empty rows. I know that I have to loop through the file however I do not know how to do this process.
Any suggestions would be appreciate it.
public class Program
{
static void Main(string[] args)
{
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Santander .csv");
var fileContents = ReadFile(filePath);
foreach (var line in fileContents)
{
Console.WriteLine(line);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
public static IList<string> ReadFile(string fileName)
{
var results = new List<string>();
var target = File.ReadAllLines(fileName).ToList();
return results;
}
}
Use a Where clause to keep only rows that are not NullOrWhiteSpace (null, empty or only white spaces):
public static IList<string> ReadFile(string fileName)
{
return File.ReadAllLines(fileName)
.Where(line => !string.IsNullOrWhiteSpace(line))
.ToList();
}
After better understanding what you are after for then: For each line use Split to get the different columns and then check that the first 2 are not empty:
public static IList<string> ReadFile(string fileName)
{
return (from line in File.ReadAllLines(fileName)
where !string.IsNullOrWhiteSpace(line)
let columns = line.Split(',')
where columns.Length >= 2 &&
!string.IsNullOrWhiteSpace(columns[0]) &&
!string.IsNullOrWhiteSpace(columns[1])
select line).ToList();
}
Changed to syntax query just because in my opinion it is cleaer when we start needing things like let
If what you want is get all the column values from the file without the empty ones then:
public static IList<string> ReadFile(string fileName)
{
File.ReadAllLines(fileName)
.SelectMany(line => line.Split(','))
.Where(item => !string.IsNullOrWhiteSpace(item))
.ToList();
}
If you are not familiar/comfortable with Linq then another aproach is like this.
public static IList<string> ReadFile(string fileName)
{
var results = new List<string>();
string[] target = File.ReadAllLines(fileName);
foreach (string line in target)
{
var array = line.Split(','); //If your csv is seperated by ; then replace the , with a ;
if (!string.IsNullOrWhiteSpace(array[0]) && !string.IsNullOrWhiteSpace(array[1]) && array.Length >= 2)
results.Add(line);
}
return results;
}
target can still be defined as var, but I've defined it as string[] to make it more obvious that you can then do foreach over the array.
However I like Gilad Green's solution using Linq. I'm less familiar with it so it's not the first solution I think of, but I think it's worth getting familiar with.

Filtering strings out of an array

I'm trying to design a check on incoming strings for an array, and if the incoming string has a specific starting character it gets skipped over
For example:
;item1
item2
item3
;item4
should be put into array as
item2
item3
I thought I'd try to use a foreach method to skip the line that starts with the identifier, and then in the else append the lines that don't match back into the string array, but it doesn't seem I am able to do this.
Help!
void Whitelist()
{
if (logging == 1)
{
FIO._Log("Performing WhiteList func", writer);
}
try
{
string[] lines = File.ReadAllLines("Whitelist.ini");
string[] lines2;
foreach (string line in lines)
{
if (line.StartsWith(";"))
{
continue;
}
else
{
// lines2.append(line) ??
}
}
structs.CustomWhiteList = lines2;
}
catch (Exception e)
{
MessageBox.Show("Error reading whitelist file." + Environment.NewLine + e.Message);
FIO._Log("Failed to read whitelist file", writer);
}
}
You can read the lines in, filter out the ones starting with a semicolon, and then set the resulting array directly to CustomWhiteList.
Try the following code:
var lines = File.ReadAllLines("Whitelist.ini");
structs.CustomWhiteList = lines.Where(x => !x.StartsWith(";")).ToArray();
This uses LINQ, so you'll have to add using System.Linq to your class if it's not already there.

Need to remove values from an ArrayList in C#

So I have been asked to remove tour codes that end with the letter G, GE, G=, or Z. The only bad thing is I believe we use this call for a lot of pages and that is the reason I cant alter the database call in the first place so I want to do this specifically for this one person. My code is calling an arrayList that fills with all the tourcodes we have. Is there any way I can remove the tours with the letters above. Here is what I got to work with.
public void LoadTourCodes()
{
ddlTourCode.Items.Clear();
if (ddlTourCode.Visible)
{
ddlTourCode.Items.Add(new ListItem(" ", ""));
ArrayList tourCodes;
tourCodes = EblTipTours.FindTourCodes();
foreach (string tourCode in tourCodes)
{
ddlTourCode.Items.Add(tourCode);
}
}
}
You can do it using LINQ, like this:
var toRemove = new []{"G", "GE", "G=", "Z"};
foreach (string tourCode in tourCodes.Where(code => !toRemove.Any(suffix => code.EndsWith(suffix)))) {
ddlTourCode.Items.Add(tourCode);
}
If you cannot use LINQ because it's a legacy system, you can rewrite the code like this:
string[] toRemove = new string[] {"G", "GE", "G=", "Z"};
foreach (string tourCode in tourCodes) {
bool good = true;
foreach (string suffix in toRemove) {
if (tourCode.EndsWith(suffix)) {
good = false;
break;
}
}
if (!good) continue;
ddlTourCode.Items.Add(tourCode);
}

Speedily Read and Parse Data

As of now, I am using this code to open a file and read it into a list and parse that list into a string[]:
string CP4DataBase =
"C:\\Program\\Line Balancer\\FUJI DB\\KTS\\KTS - CP4 - Part Data Base.txt";
CP4DataBaseRTB.LoadFile(CP4DataBase, RichTextBoxStreamType.PlainText);
string[] splitCP4DataBaseLines = CP4DataBaseRTB.Text.Split('\n');
List<string> tempCP4List = new List<string>();
string[] line1CP4Components;
foreach (var line in splitCP4DataBaseLines)
tempCP4List.Add(line + Environment.NewLine);
string concattedUnitPart = "";
foreach (var line in tempCP4List)
{
concattedUnitPart = concattedUnitPart + line;
line1CP4PartLines++;
}
line1CP4Components = new Regex("\"UNIT\",\"PARTS\"", RegexOptions.Multiline)
.Split(concattedUnitPart)
.Where(c => !string.IsNullOrEmpty(c)).ToArray();
I am wondering if there is a quicker way to do this. This is just one of the files I am opening, so this is repeated a minimum of 5 times to open and properly load the lists.
The minimum file size being imported right now is 257 KB. The largest file is 1,803 KB. These files will only get larger as time goes on as they are being used to simulate a database and the user will continually add to them.
So my question is, is there a quicker way to do all of the above code?
EDIT:
***CP4***
"UNIT","PARTS"
"BLOCK","HEADER-"
"NAME","106536"
"REVISION","0000"
"DATE","11/09/03"
"TIME","11:10:11"
"PMABAR",""
"COMMENT",""
"PTPNAME","R160805"
"CMPNAME","R160805"
"BLOCK","PRTIDDT-"
"PMAPP",1
"PMADC",0
"ComponentQty",180
"BLOCK","PRTFORM-"
"PTPSZBX",1.60
"PTPSZBY",0.80
"PTPMNH",0.25
"NeedGlue",0
"BLOCK","TOLEINF-"
"PTPTLBX",0.50
"PTPTLBY",0.40
"PTPTLCL",10
"PTPTLPX",0.30
"PTPTLPY",0.30
"PTPTLPQ",30
"BLOCK","ELDT+" "PGDELSN","PGDELX","PGDELY","PGDELPP","PGDELQ","PGDELP","PGDELW","PGDELL","PGDELWT","PGDELLT","PGDELCT","PGDELR"
0,0.000,0.000,0,0,0.000,0.000,0.000,0.000,0.000,0.000,0
"BLOCK","VISION-"
"PTPVIPL",0
"PTPVILCA",0
"PTPVILB",0
"PTPVICVT",10
"PENVILIT",0
"BLOCK","ENVDT"
"ELEMENT","CP43ENVDT-"
"PENNMI",1.0
"PENNMA",1.0
"PENNZN",""
"PENNZT",1.0
"PENBLM",12
"PENCRTS",0
"PENSPD1",100
"PTPCRDCT",0
"PENVICT",1
"PCCCRFT",1
"BLOCK","CARRING-"
"PTPCRAPO",0
"PTPCRPCK",0
"PTPCRPUX",0.00
"PTPCRPUY",0.00
"PTPCRRCV",0
"BLOCK","PACKCLS-"
"FDRTYPE","Emboss"
"TAPEWIDTH","8mm"
"FEEDPITCH",4
"REELDIAMETER",0
"TAPEDEPTH",0.0
"DOADVVACUUM",0
"CHKBEFOREFEED",0
"TAPEARMLENGTH",0
"PPCFDPP",0
"PPCFDEC",4
"PPCMNPT",30
"UNIT","PARTS"
"BLOCK","HEADER-"
"NAME","106653"
"REVISION","0000"
"DATE","11/09/03"
"TIME","11:10:42"
"PMABAR",""
"COMMENT",""
"PTPNAME","0603R"
"CMPNAME","0603R"
"BLOCK","PRTIDDT-"
"PMAPP",1
"PMADC",0
"ComponentQty",18
"BLOCK","PRTFORM-"
"PTPSZBX",1.60
"PTPSZBY",0.80
"PTPMNH",0.23
"NeedGlue",0
"BLOCK","TOLEINF-"
"PTPTLBX",0.50
"PTPTLBY",0.34
"PTPTLCL",0
"PTPTLPX",0.60
"PTPTLPY",0.40
"PTPTLPQ",30
"BLOCK","ELDT+" "PGDELSN","PGDELX","PGDELY","PGDELPP","PGDELQ","PGDELP","PGDELW","PGDELL","PGDELWT","PGDELLT","PGDELCT","PGDELR"
0,0.000,0.000,0,0,0.000,0.000,0.000,0.000,0.000,0.000,0
"BLOCK","VISION-"
"PTPVIPL",0
"PTPVILCA",0
"PTPVILB",0
"PTPVICVT",10
"PENVILIT",0
"BLOCK","ENVDT"
"ELEMENT","CP43ENVDT-"
"PENNMI",1.0
"PENNMA",1.0
"PENNZN",""
"PENNZT",1.0
"PENBLM",12
"PENCRTS",0
"PENSPD1",80
"PTPCRDCT",0
"PENVICT",1
"PCCCRFT",1
"BLOCK","CARRING-"
"PTPCRAPO",0
"PTPCRPCK",0
"PTPCRPUX",0.00
"PTPCRPUY",0.00
"PTPCRRCV",0
"BLOCK","PACKCLS-"
"FDRTYPE","Emboss"
"TAPEWIDTH","8mm"
"FEEDPITCH",4
"REELDIAMETER",0
"TAPEDEPTH",0.0
"DOADVVACUUM",0
"CHKBEFOREFEED",0
"TAPEARMLENGTH",0
"PPCFDPP",0
"PPCFDEC",4
"PPCMNPT",30
... the file goes on and on and on.. and will only get larger.
The REGEX is placing each "UNIT PARTS" and the following code until the NEXT "UNIT PARTS" into a string[].
After this, I am checking each string[] to see if the "NAME" section exists in a different list. If it does exist, I am outputting that "UNIT PARTS" at the end of a textfile.
This bit is a potential performance killer:
string concattedUnitPart = "";
foreach (var line in tempCP4List)
{
concattedUnitPart = concattedUnitPart + line;
line1CP4PartLines++;
}
(See this article for why.) Use a StringBuilder for repeated concatenation:
// No need to use tempCP4List at all
StringBuilder builder = new StringBuilder();
foreach (var line in splitCP4DataBaseLines)
{
concattedUnitPart.AppendLine(line);
line1CP4PartLines++;
}
Or even just:
string concattedUnitPart = string.Join(Environment.NewLine,
splitCP4DataBaseLines);
Now the regex part may well also be slow - I'm not sure. It's not obvious what you're trying to achieve, whether you need regular expressions at all, or whether you really need to do the whole thing in one go. Can you definitely not just process it line by line?
You could achieve the same output list 'line1CP4Components' using the following:
Regex StripEmptyLines = new Regex(#"^\s*$", RegexOptions.Multiline);
Regex UnitPartsMatch = new Regex(#"(?<=\n)""UNIT"",""PARTS"".*?(?=(?:\n""UNIT"",""PARTS"")|$)", RegexOptions.Singleline);
string CP4DataBase =
"C:\\Program\\Line Balancer\\FUJI DB\\KTS\\KTS - CP4 - Part Data Base.txt";
CP4DataBaseRTB.LoadFile(CP4DataBase, RichTextBoxStreamType.PlainText);
List<string> line1CP4Components = new List<string>(
UnitPartsMatch.Matches(StripEmptyLines.Replace(CP4DataBaseRTB.Text, ""))
.OfType<Match>()
.Select(m => m.Value)
);
return line1CP4Components.ToArray();
You may be able to ignore the use of StripEmptyLines, but your original code is doing this via the Where(c => !string.IsNullOrEmpty(c)). Also your original code is causing the '\r' part of the "\r\n" newline/linefeed pair to be duplicated. I assumed this was an accident and not intentional?
Also you don't seem to be using the value in 'line1CP4PartLines' so I omitted the creation of the value. It was seemingly inconsistent with the omission of empty lines later so I guess you're not depending on it. If you need this value a simple regex can tell you how many new lines are in the string:
int linecount = new Regex("^", RegexOptions.Multiline).Matches(CP4DataBaseRTB.Text).Count;
// example of what your code will look like
string CP4DataBase = "C:\\Program\\Line Balancer\\FUJI DB\\KTS\\KTS - CP4 - Part Data Base.txt";
List<string> Cp4DataList = new List<string>(File.ReadAllLines(CP4DataBase);
//or create a Dictionary<int,string[]> object
string strData = string.Empty;//hold the line item data which is read in line by line
string[] strStockListRecord = null;//string array that holds information from the TFE_Stock.txt file
Dictionary<int, string[]> dctStockListRecords = null; //dictionary object that will hold the KeyValuePair of text file contents in a DictList
List<string> lstStockListRecord = null;//Generic list that will store all the lines from the .prnfile being processed
if (File.Exists(strExtraLoadFileLoc + strFileName))
{
try
{
lstStockListRecord = new List<string>();
List<string> lstStrLinesStockRecord = new List<string>(File.ReadAllLines(strExtraLoadFileLoc + strFileName));
dctStockListRecords = new Dictionary<int, string[]>(lstStrLinesStockRecord.Count());
int intLineCount = 0;
foreach (string strLineSplit in lstStrLinesStockRecord)
{
lstStockListRecord.Add(strLineSplit);
dctStockListRecords.Add(intLineCount, lstStockListRecord.ToArray());
lstStockListRecord.Clear();
intLineCount++;
}//foreach (string strlineSplit in lstStrLinesStockRecord)
lstStrLinesStockRecord.Clear();
lstStrLinesStockRecord = null;
lstStockListRecord.Clear();
lstStockListRecord = null;
//Alter the code to fit what you are doing..

Categories