I have text file which contains line like this:
#relation SMILEfeatures
#attribute pcm_LOGenergy_sma_range numeric
#attribute pcm_LOGenergy_sma_maxPos numeric
#attribute pcm_LOGenergy_sma_minPos numeric...
Where are about 6000 lines of these attributes, after attributes where are lines like this:
#data
1.283827e+01,3.800000e+01,2.000000e+00,5.331364e+00
1.850000e+02,4.054457e+01,4.500000e+01,3.200000e+01...
I need to seperate these strings in two different arrays. So far I only managed to store everything in one array.
Here is my code for storing in array:
using (var stream = new FileStream(filePath, FileMode.OpenOrCreate))
{
using (var sr = new StreamReader(stream))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
}
string allines = sb.ToString();
Console.WriteLine(sb);
}
All strings after #relation SMILEfeatures and contains #attribute are stored in first array. All the strings after #data should are stored in the second array. Hope this is what you wanted.
var relationLineNumbers = new List<int>();
var dataLineNumbers = new List<int>();
var relation = new StringBuilder();
var data = new List<string>();
using (var stream = new FileStream(filepath, FileMode.OpenOrCreate))
{
using (var sr = new StreamReader(stream))
{
string line;
bool isRelation = false;
bool isData = false;
int lineNumber = 0;
while ((line = sr.ReadLine()) != null)
{
lineNumber++;
if (line.StartsWith("#relation SMILEfeatures"))
{
isRelation = true;
isData = false;
continue;
}
if (line.StartsWith("#data"))
{
isData = true;
isRelation = false;
continue;
}
if (isRelation)
{
if (line.StartsWith("#attribute"))
{
relation.Append(line);
relationLineNumbers.Add(lineNumber);
}
}
if (isData)
{
data.AddRange(line.Split(','));
dataLineNumbers.Add(lineNumber);
}
}
}
Console.WriteLine("Relation");
Console.WriteLine(relation.ToString());
Console.WriteLine("Data");
data.ForEach(Console.WriteLine);
All strings which starts with #relation SMILEfeatures and contains #attribute should be stored in first array. Numbers which starts with #data should be stored in second array.
Use string.Contains() and string.StatsWith() for checking.
Read every line and decide in wich array / list you want to put this line
void ReadAndSortInArrays(string fileLocation)
{
List<string> noData = new List<string>();
List<string> Data = new List<string>();
using(StreamReader sr = new StreamReader(fileLocation))
{
string line;
while(!sr.EndOfStream)
{
line = sr.ReadLine();
if(line.StartsWith("#relation") && line.Contains("#attribute"))
{
noData.Add(line);
}
else if(line.StartsWith("#data")
{
Data.Add(line);
}
else
{
// This is stange
}
}
}
var noDataArray = noData.ToArray();
var DataArray = Data.ToArray();
}
But i think that not every line is beginning with "#data"
So you may want to Read all lines and do somethink like this:
string allLines;
using(StreamReader sr = new StreamReader(yourfile))
{
allLines = = sr.ReadToEnd();
}
var arrays = allLines.Split("#data");
// arrays[0] is the part before #data
// arrays[1] is the part after #data (the numbers)
// But array[1] does not contain #data
The question is not really very clear. But my take is, collect all lines that start with #relation or #attribute in one bucket, then collect all number lines in another bucket. I have chosen to ignore the #data lines, as they do not seem to contain any extra information.
Error checking may be performed by making sure that the data lines (i.e. number lines) contain comma separated lists of parsable numerical values.
var dataLines = new List<string>();
var relAttLines = new List<string>();
foreach (var line in File.ReadAllLines())
{
if (line.StartsWith("#relation") || line.StartsWith("#attribute"))
relAttLines.Add(line);
else if (line.StartsWith("#data"))
//ignore these
continue;
else
dataLines.Add(line);
}
Related
I want to ping the hostnames that are in the csv and write the result in the next column, but I'm little bit lost how to do it?
This the error I get:Error CS0021 Cannot apply indexing with [] to an expression of type 'StreamReader'
And the only thing I can do is write to the console what is in the csv.
string filePath = #"c:\hostnames.csv";
var reader = new StreamReader(filePath);
Ping ping = new Ping();
List<string> hostnames = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
hostnames.Add(values[0]);
hostnames.ForEach(Console.WriteLine);
}
List<string> goodPing = new List<string>();
foreach (string singleComputer in hostnames)
{
PingReply pingresult = ping.Send(singleComputer);
if (pingresult.Status.ToString() == "Success")
{
goodPing.Add(singleComputer);
}
}
var csv = new StringBuilder();
var first = reader[0].ToString();
var newLine = string.Format("{0}");
csv.AppendLine(newLine);
File.WriteAllText(filePath, csv.ToString());
}
It is not clear what error you are getting is but one issue I noticed is you are not providing a variable to string.Format which I think it is useless at there..
Example hostnames.csv is something like this I assume:
www.google.com,www.somebadu-rlwhichcannot..com,www.stackoverflow.com
var filePath = #"c:\test\hostnames.csv"; // change it to your source
var filePathOutput = #"c:\test\hostnamesOutput.csv"; // use separate output file so you would not overwrite your source..
var ping = new Ping();
var hostNames = new List<string>();
using (var reader = new StreamReader(filePath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
hostNames = line.Split(',').ToList();
}
}
var goodPing = new List<string>();
foreach (var singleComputer in hostNames)
try
{
var pingResult = ping.Send(singleComputer);
if (pingResult.Status == IPStatus.Success)
{
goodPing.Add(singleComputer);
}
}
catch (Exception e)
{
// host was not in a correct format or any other exception thrown....
// do whatever error handling you want, logging etc...
}
var csv = new StringBuilder();
foreach (var hostname in hostNames)
{
var resultText = goodPing.Contains(hostname) ? "Success" : "Failed";
var newLine = string.Format("{0},{1}", hostname, resultText);
csv.AppendLine(newLine);
}
File.WriteAllText(filePathOutput, csv.ToString());
I didn't try on IDE but it should be doing what you are trying to do. Seems you copy pasted that code from somewhere and tried to manipulate it without understanding. I would suggest to make sure you understand it line by line why it is used, how it is used before you start using it. Otherwise you will always need someone to write the code for you!
Output will be (in excel):
Here is a simplified version of what I think you are trying to do.
Example hostheaders.csv before code runs
www.google.com
www.stackoverflow.com
www.fakewebsitehere.com
Updated code
string filePath = #"c:\hostnames.csv";
List<string> results = new List<string>();
using (var reader = new StreamReader(filePath))
{
Ping ping = new Ping();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
var hostname = values[0];
Console.WriteLine(hostname);
PingReply pingresult = ping.Send(hostname);
results.Add($"{line},{pingresult.Status.ToString()}");
}
}
File.WriteAllLines(filePath, results);
hostheaders.csv after code runs
www.google.com,Success
www.stackoverflow.com,Success
www.fakewebsitehere.com,TimedOut
I am reading the file which has data as below
123456788|TUUKKA|RASK|01/01/85|HOCKEY|123
123456786|TOM|BRADY|01/01/75|FOOTBALL|123
123456787|RAJON|RONDO|01/01/80|BASKETBALL|ABC
123456785|DUSTIN|PEDROIA|01/01/83|BASEBALL|
123456789|DAVID|ORTIZ|01/01/77|BASEBALL|123
and splitting it with the delimiter '|', but I am the stream reader is not reading the line 4 which contains a null at the end.How do I handle this?
This is my code for reading and splitting the text file line
string s = string.Empty;
using (System.IO.StreamReader File = new System.IO.StreamReader(Path))
{
File.ReadLine();//Removing the first line
while ((s = File.ReadLine()) != null)
{
string[] str = s.Split('|');
UpdateRecords.Athelete(str);
}
}
this is my UpdateRecords.Athelete(str) code:
public static void Athelete(string[] Records) {
tblAthlete athlete = new tblAthlete();
using (SportEntities sportEntities = new SportEntities()) {
var temp = Convert.ToInt32(Records[0]);
if (sportEntities.tblAthletes.FirstOrDefault(x => x.SSN == temp) == null) {
athlete.SSN = Convert.ToInt32(Records[0]);
athlete.First_Name = Records[1];
athlete.Last_Name=Records[2];
athlete.DOB = Convert.ToDateTime(Records[3]);
athlete.SportsCode = Records[4];
athlete.Agency_Code = Records[5];
sportEntities.tblAthletes.Add(athlete);
sportEntities.SaveChanges();
}
}
}
If we put:
athlete.Agency_Code = Records[5];
together with (from comments):
The column is an FK referenced to another table PK and it can accept null values.
the problem becomes clear. An empty string ("") is not a null; it is an empty string! It sounds like you simply want something like:
var agencyCode = Records[5];
athlete.Agency_Code = string.IsNullOrEmpty(agencyCode) ? null : agencyCode;
I am trying to create a List for every file available in a directory. Each file must have a separate list of items. I have created a list, but it shows all items available in all files. How to do it? Need help in this regard.
I am doing it like this, but it shows all Items "Product" in all files:
a piece of code is here:
List products = new List();
foreach (string file in fileList)
{
using (StreamReader sr = new StreamReader(file))
{
string line;
while ((line = sr.ReadLine()) != null)
{
rows++;
if (line.StartsWith("Product"))
{
var val = line.Split(',');
upc = val[1];
pName = val[3];
products.Add(upc);
products.Add(pName);
productList = string.Join(",", products.ToArray());
Add these clases
public class ProductFile
{
public string Name;
public List<Product> Products = new List<Product>();
}
public class Product
{
public string Upc;
public string PName;
}
And then, in your code:
var productFiles = new List<ProductFile>();
foreach (string file in fileList)
{
var productFile = new ProductFile(){ Name = Path.GetFileName(file) };
using (StreamReader sr = new StreamReader(file))
{
string line;
while ((line = sr.ReadLine()) != null)
{
rows++;
if (line.StartsWith("Product"))
{
var val = line.Split(',');
var product = new Product()
{
Upc = val[1],
PName = val[3]
};
productFile.Products.Add(product); //Adds a product
}
}
};
productFiles.Add(productFile); //Adds a file
}
I have two different function to handle two different types of my input text file. One text file with double quotes and one without double quotes.
I wanted to know how can i combine these two functions to a common single function where i can handle in a more efficient way
Code:
//this the function to handle text file without double quotes
public void stack1()
{
string old;
string iniPath = Application.StartupPath + "\\list.ini";
bool isDeleteSectionFound = false;
List<string> deleteCodeList = new List<string>();
using (StreamReader sr = File.OpenText(iniPath))
{
while ((old = sr.ReadLine()) != null)
{
if (old.Trim().Equals("[DELETE]"))
{
isDeleteSectionFound = true;
}
if (isDeleteSectionFound && !old.Trim().Equals("[DELETE]"))
{
deleteCodeList.Add(old.Trim());
}
}
}
StringBuilder sb = new StringBuilder();
using (StreamReader reader = File.OpenText(textBox1.Text))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var value = line.Split('\t');
bool deleteLine = value.Any(v => deleteCodeList.Any(w => v.Equals(w)));
if (!deleteLine)
{
sb.Append(line + Environment.NewLine);
}
}
}
File.WriteAllText(textBox1.Text, sb.ToString());
//return;
}
//this the function to handle text file with double quotes
public void stack()
{
string old;
string iniPath = Application.StartupPath + "\\list.ini";
bool isDeleteSectionFound = false;
List<string> deleteCodeList = new List<string>();
using (StreamReader sr = File.OpenText(iniPath))
{
while ((old = sr.ReadLine()) != null)
{
if (old.Trim().Equals("[DELETE]"))
{
isDeleteSectionFound = true;
}
if (isDeleteSectionFound && !old.Trim().Equals("[DELETE]"))
{
deleteCodeList.Add(old.Trim());
}
}
}
StringBuilder sb = new StringBuilder();
using (StreamReader reader = File.OpenText(textBox1.Text))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split('\t').Select(v => v.Trim(' ', '"'));
bool deleteLines = values.Any(v => deleteCodeList.Any(w => v.Equals(w)));
if (!deleteLines)
{
sb.Append(line + Environment.NewLine);
}
}
}
File.WriteAllText(textBox1.Text, sb.ToString());
MessageBox.Show("finish");
}
The only difference between these two functions is this line:
// stack1 function
var value = line.Split('\t');
// stack2 function
var values = line.Split('\t').Select(v => v.Trim(' ', '"'));
The simplest way would probably be to add a parameter to your method, and then add the check after the split:
public void Split(bool shouldTrimQuotes)
{
...
IEnumerable<string> value = line.Split('\t');
if (shouldTrimQuotes)
{
value = value.Select(v => v.Trim(' ', '"'));
}
...
}
In one case, you would pass true as the parameter (which will cause quotes to be trimmed), while in the second one you would pass false to indicate you don't want to trim them:
// split, but don't trim quotes before comparison
Split(shouldTrimQuotes: false);
// split, trim quotes before comparison
Split(shouldTrimQuotes: true);
You might also play a bit and try to refactor the whole thing, trying to extract smaller general pieces of code into separate methods which might make it clearer what they are doing. This is one approach, for example:
// rewrites the specified file, removing all lines matched by the predicate
public static void RemoveLinesFromFile(string filename, Func<string, bool> match)
{
var linesToKeep = File.ReadAllLines(filename)
.Where(line => match(line))
.ToList();
File.WriteAllLines(filename, linesToKeep);
}
// gets the list of "delete codes" from the specified ini file
public IList<string> GetDeleteCodeList(string iniPath)
{
return File.ReadLines(iniPath)
.SkipWhile(l => l.Trim() != "[DELETE]")
.Skip(1).ToList();
}
// removes lines from a tab-delimited file, where the specified listOfCodes contains
// at least one of the tokens inside that line
public static void RemoveLinesUsingCodeList(
string filename,
IList<string> listOfCodes,
bool shouldTrimQuotes)
{
RemoveLinesFromFile(filename, line =>
{
IEnumerable<string> tokens = line.Split('\t');
if (shouldTrimQuotes)
{
tokens = tokens.Select(v => v.Trim(' ', '"'));
}
return (tokens.Any(t => listOfCodes.Any(t.Equals)));
});
}
This program is meant to read in a csv file and create a dictionary from it, which is then used to translate a word typed into a textbox (txtINPUT) and output the result to another textbox (txtOutput).
The program doesnt translate anything and always outputs "No translation found."
I've never used the dictionary class before so I dont know where the problem is coming from.
Thanks for any help you can give me.
Dictionary<string, string> dictionary;
private void CreateDictionary()
{
//Load file
List<string> list = new List<string>();
using (StreamReader reader = new StreamReader("dictionarylist.csv"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//Add to dictionary
dictionary = new Dictionary<string, string>();
string[] split = line.Split(',');
dictionary.Add(split[0], split[1]);
}
}
}
private void btnTranslate_Click(object sender, EventArgs e)
{
CreateDictionary();
string outputString = null;
if (dictionary.TryGetValue(txtInput.Text, out outputString))
{
txtOutput.Text = outputString;
}
else
{
txtOutput.Text = ("No translation found");
}
}
You are creating a new instance of a Dictionary each loop cycle, basically overwriting it each time you read a line. Move this line out of the loop:
// Instantiate a dictionary
var map = new Dictionary<string, string>();
Also why not load dictionary one time, you are loading it each button click, this is not efficient.
(>=.NET 3) The same using LINQ ToDictionary():
usign System.Linq;
var map = File.ReadAllLines()
.Select(l =>
{
var pair = l.Split(',');
return new { First = pair[0], Second = pair[1] }
})
.ToDictionary(k => k.First, v => v.Second);
In your while loop, you create a new dictionary every single pass!
You want to create one dictionary, and add all the entries to that:
while ((line = reader.ReadLine()) != null)
{
//Add to dictionary
dictionary = new Dictionary<string, string>(); /* DON'T CREATE NEW DICTIONARIES */
string[] split = line.Split(',');
dictionary.Add(split[0], split[1]);
}
You should do it more like this:
List<string> list = new List<string>();
dictionary = new Dictionary<string, string>(); /* CREATE ONE DICTIONARY */
using (StreamReader reader = new StreamReader("dictionarylist.csv"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
string[] split = line.Split(',');
dictionary.Add(split[0], split[1]);
}
}