I am trying to parse a column (File is composed of only 1 column filled with double numbers.) in a .csv file but C# throws me error when it encounters an empty cell.
{"Input string was not in a correct format."}
I want program to continue with the next cell when this happens. Is there a way?
Note: I tried
if(array[i] != null)
but this does not seem to work.
I use this block to read from .csv:
var column = new List<string>();
using (var rd = new StreamReader(#"pathofthecsvfile"))
{
while (!rd.EndOfStream)
{
var splits = rd.ReadLine().Split(';');
column.Add(splits[0]);
}
}
string[] arr = column.ToArray();
double[] array = new double[arr.Length];
//problem is in this block
for (int i = 0; i < array.Length; i++)
{
if (arr[i] != null)
{
array[i] = Convert.ToDouble(arr[i]);
}
}
I would check it when inserting:
if split[0] != null && split[0] != "" {
column.Add(splits[0]);
}
You are not validating the data you are loading into the array to see if it is in a valid format - Convert.ToDouble will fail for a number of reasons other than just null value and empty string.
If you are happy just to skip to next column, use a TryParse instead in the for loop:
double.TryParse(arr[i], out array[i]);
Related
My old method (other than being wrong in general) takes too long to get multiple lines from a file and then store the parameters into a dictionary.
Essentially it's open file, grab every second line one at a time, modify the line then store the data (line pos and the first element of the line (minus) ">") close the file and then repeat.
for (int i = 0; i < linecount - 1; i += 2)
{
string currentline = File.ReadLines
(datafile).Skip(i).Take(1).First();
string[] splitline = currentline.Split(' ');
string filenumber = splitline[0].Trim('>');
} for (int i = 0; i < linecount - 1; i += 2)
You need to read next line inside while loop, otherwise loop body will always analyse first line (that's why there are Dictionary error) and never exist:
while (line != null)
{
// your current code here
line = sr.ReadLine();
}
The issue is that you only ever read the first line of the file. To solve this you need to ensure you call sr.ReadLine() on every iteration through the loop. This would look like:
using (StreamReader sr = File.OpenText(datafile))
{
string line = sr.ReadLine();
while (line != null)
{
count = count ++;
if (count % 2 == 0)
{
string[] splitline = line.Split(' ');
string datanumber = splitline[0].Trim('>');
index.Add(datanumber, count);
}
line = sr.ReadLine();
}
}
This means on each iteration, the value of line will be a new value (from the next line of the file).
I write some data into csv file from List but some list indexes has empty string but another indexes has value
in these cases the data compared with another list wrote in the same csv file
this is my csv file opened using excel sheet
in the third column there exist ID for the the second column cell so in the coming rows i want to detect the name of the ID based on previous rows
like in row 3 it's ID is 19 and name is I/O so in the 7th row the ID is 19 and want to fill the second cell now
info : the IDs is already known above and any next ID will be exist before
by the follwing code.
bool isInList = ms.IndexOf(ShapeMaster) != -1;
if (isInList)
{
savinglabelnamefortextbox = t.InnerText;
string replacement =
Regex.Replace(savinglabelnamefortextbox, #"\t|\n|,|\r", "");
xl.Add("");
dl.Add(replacement);
ms.Add(ShapeMaster);
}
and I use the following code to write to the csv file
using (StreamWriter sw = File.CreateText(csvfilename))
{
for (int i = 0; i < dl.Count; i++)
{
var line = String.Format("{0},{1},{2}", dl[i], xl[i],ms[i]);
sw.WriteLine(line);
}
}
Try this
for (int x = 0; x < ms.Count; x++)
{
if (xl[x] != "")
{
continue;
}
else if (xl[x] == "")
{
for (int y = 0; y<xl.Count; y++)
{
if (ms[y] == ms[x])
{
xl[x] = xl[y];
break;
}
}
continue;
}
}
I'm attempting to parse a text file containing data that is being used on a remote FTP server. The data is delimited by an equals sign (=) and I'm attempting to load each row in to two columns in a DataGridView. The code I have written works fine except for when an equals character is thrown into the second column's value. When this happens, regardless of specifying the maximum count as being 2. I'd prefer not to change the delimiter if possible.
Here is the code that is being problematic:
dataGrid_FileContents.Rows.Clear();
char delimiter = '=';
StreamReader fileReader = new StreamReader(fileLocation);
String fileData = fileReader.ReadToEnd();
String[] rows = fileData.Split("\n".ToCharArray());
for(int i = 0; i < rows.Length; i++)
{
String str = rows[i];
String[] items = str.Split(new char[] { delimiter }, 1, StringSplitOptions.RemoveEmptyEntries);
if (items.Length == 2)
{
dataGrid_FileContents.Rows.Add(items[0], items[1]);
}
}
fileReader.Close();
And an example of the file being loaded:
boats=123
cats=234-f
cars==1
It works as intended for the first two rows and then ignores the last row as it ends up creating a String[] with 1 element and two String[]s with zero elements.
Try the following. It will capture the value before and after the first '=', correctly parsing the cars==1 scenario.
String[] items = str.Split(new char[] { delimiter }, 2, stringSplitOptions.None);
A different solution, if you want everything after the first equals then you could approach this problem using string.IndexOf
for(int i = 0; i < rows.Length; i++)
{
String str = rows[i];
int pos = str.IndexOf(delimiter);
if (pos != -1)
{
string first = str.Substring(0, pos-1);
string second = str.Substring(pos + 1);
dataGrid_FileContents.Rows.Add(first, second);
}
}
Just read all items delimeted by '=' in row.
Then iterate over items, and check, that item not empty, than use this prepared data to write
here illustrated snippet
http://dotnetfiddle.net/msVho2
and your snippet can be transformed to something like bellow
dataGrid_FileContents.Rows.Clear();
char delimiter = '=';
using(StreamReader fileReader = new StreamReader(fileLocation))
{
string[] data = new string[2];
while(true)
{
string row = fileReader.ReadLine();
if(row == null)
break;
string[] items = row.Split(delimiter);
int data_index = 0;
foreach(string item in items)
{
if(data_index >= data.Length)
{
//TODO: log warning
break;
}
if(!string.IsNullOrWhiteSpace(item))
{
data[data_index++] = item;
}
}
if(data_index < data.Length)
{
//TODO: log error, only 1 item in row
continue;
}
dataGrid_FileContents.Rows.Add(data[0], data[1]);
}
}
I have written a coding which extracts specific lines from a text file, split the lines and insert the data to a gridview. The coding is give below.
Unfortunately, when i execute this program, i receive an error msg called "Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index". Please help me to identify what went wrong in my codings
string line;
System.IO.StreamReader file = new System.IO.StreamReader("test.txt");
while ((line = file.ReadLine()) != null)
{
if (line.Contains("DISKXFER"))
{
string dataLine=line.ToString();
string[] split = dataLine.Split(',');
for (int i = 0; i < split.Length; i++)
{
for (int j = 1; j < dataLine.Length; j++)
{
dataGridView1.Rows[j].Cells[i].Value = split[i];
}
}
}
}
Your DataGridView does not contain the number of rows required to hold the information. Instead of setting dataGridView1.Rows[j].Cells[i] to some value, you need to add one row for every entry in dataLine.
Instead of your nested loop you could do this:
string dataLine=line.ToString();
string[] split = dataLine.Split(',');
dataGridView1.Rows.Add(split);
This page show you an example http://www.dotnetperls.com/convert-list-datatable, for more information about datagridview http://www.dotnetperls.com/datagridview
I am parsing my data output, however, my data has return charicters in it (\n). So when I run my code, the array is built and one of the arrays (4) is blank data... I have tried using null, "", and " ". Would anyone know how I can prevent that last array from showing?
char[] returnChar= {'\n' };
string parseText = captcha;
string[] words = parseText.Split(returnChar);
int count = words.Length;
for (int i = 0; i < count; i++)
{
if (words[i] == null)
{
MessageBox.Show("This row is empty: " + i);
}
MessageBox.Show(words[i]);
}
When doing String.Split, define the second parameter - StringSplitOptions.
string[] words =
parseText.Split(returnChar, StringSplitOptions.RemoveEmptyEntries);
This way it will skip over empty elements.