This question already has answers here:
Parsing CSV files in C#, with header
(19 answers)
Closed 8 years ago.
This question has been asked several times with different inputs so I thought of reposting it with my requirement.
I have a CSV file which contents string fields in the way given below.
idnum,name1, name2,groupid
idnum,name1, name2,groupid
idnum,name1, name2,groupid
example
s001,sahil,payap,gid0
s002,Amir,Khan,gid02
d003,hrithik,roshan,gid03
I have two dimensional string array. I want to read row by row to my two dimensional array.
When it read it should be like this
arr[0][0]=s001
arr[0][1]=name1
arr[0][2]=name2
arr[0][3]=gid01
arr[1][0]=s002
arr[1][1]=Amir
arr[1][2]=Khan
arr[1][3]=gid04
there are 40 records in a file and it should read till the end of the file.
I need to implement this in C#
Any code sample or any explanation would be great help.
I have no knowledge in csv file handling so please don't ask what did you try, at least if you could give me a code sample for reading just one string for a variable it would be a great help.
And please don't ask to go for another solution.
Thanks.
The simplest way to read a csv file in the way you suggest is probably:
var rows = File.ReadAllLines("myfile.csv").Select(l => l.Split(',').ToArray()).ToArray();
Then:
Console.WriteLine(rows[0][0]); // Will output s001
Console.WriteLine(rows[0][1]); // Will output sahil
Console.WriteLine(rows[0][2]); // Will output payap
Console.WriteLine(rows[0][3]); // Will output gid0
Console.WriteLine(rows[1][0]); // Will output s002
Console.WriteLine(rows[2][0]); // Will output d003
The file would have to be read in line-wise. Each line would have to be separated using String.Split. Then the resulting strings would have to be trimmed using Trim, and finally would have to be written into the respective columns of the current row. However I totally second the comments above; more convenient would be to use some class or struct called Person and then to parse into a List<Person>.
The reading could be done as follows:
String line = String.Empty;
System.IO.StreamReader file = new System.IO.StreamReader("c:\\file.txt");
while((line = file.ReadLine()) != null)
{
String[] parts_of_line = line.Split(',')
for ( int i = 0; i < parts_of_line.Length; i++ )
parts_of_line[i] = parts_of_line[i].Trim();
// do with the parts of the line whatever you like
}
You can do that using the CsvHelper library:
const string Csv = #"s001,sahil,payap,gid0
s002,Amir,Khan,gid02
d003,hrithik,roshan,gid03";
var rows = new List<string[]>();
string[] row;
using (var stringReader = new StringReader(Csv))
using (var parser = new CsvParser(stringReader))
while ((row = parser.Read()) != null)
{
rows.Add(row);
}
Console.WriteLine(rows[0][0]); // Will output s001
Console.WriteLine(rows[0][1]); // Will output sahil
Console.WriteLine(rows[0][2]); // Will output payap
Console.WriteLine(rows[0][3]); // Will output gid0
Console.WriteLine(rows[1][0]); // Will output s002
Console.WriteLine(rows[2][0]); // Will output d003
For a working example, check out this .NET fiddle: http://dotnetfiddle.net/PLPXo8
If you want to read directly from file, you can do this:
var rows = new List<string[]>();
string[] row;
using (var parser = new CsvParser(File.OpenText(#"c:\test.csv")))
while ((row = parser.Read()) != null)
{
rows.Add(row);
}
Related
This question already has answers here:
split a string on newlines in .NET
(17 answers)
Closed 3 months ago.
string candidates;
string[] candidatesSplit = { };
string line;
int countLines = 0;
StreamReader sr = new StreamReader("..\\..\\..\\candidates.txt"); // Read candidates from file
candidates = sr.ReadToEnd();
sr.Close();
candidatesSplit = candidates.Split(','); // Split the file with ','
Console.WriteLine(candidatesSplit[30]);
Using this code, I wanted to split every ',' and get specific words out from my text file.
My candidates file looks like this:
100,Esra Tarak,90,D1,D4,D2,A,B,D,C, ,C,A,D,B,C,D,B,A, ,B,A,C,D,C,D,A,D,B,C,D
101,Cem Ak,84,D1,D5, ,A,C,D,C,C,C,A,C,B,C,D,B,A,C,B,A,C,D,C,C,A,D,B,C,D
Code works perfectly for the first line in candidates.txt, however when it comes to the second line on the text file, the output comes out like this:
D
101
I need it to show only like this
101
I cannot put a ',' at the end of my lines. Is there any way to fix this?
Just Split(Environment.NewLine) on the entire input first and then Split(',') again on each line.
using var sr = new StreamReader("..\\..\\..\\candidates.txt");
var candidates = sr.ReadToEnd();
foreach (var line in candidates.Split(Environment.NewLine))
{
var candidatesSplit = line.Split(',');
Console.WriteLine(candidatesSplit[30]);
}
I have a CSV that looks like this. My goal is to extract each entry (notice I said entry, not line), where an entry starts from the first column and stretches to the last column, and may span multiple lines. I'd like to extract an entry without ruining the formatting. For example, I do not want the following to be considered four seperate lines,
Eg. 1, One Column Multiple Lines
...,"1. copy ctor
2. copy ctor
3. declares function
4. default ctor",... // Where ... represents the columns before and after
but rather a column in one entry that can be represented as such
Eg. 2, One Column Single Line
"1. copy ctor\n2.copy ctor\ndeclares function\n4.default ctor"
When I iterate over the CSV, as such, I get Eg. 1. I'm not sure why splitting on a comma is treating a new line as a comma.
using (var streamReader = new StreamReader("results-survey111101.csv"))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
string[] splitLine = line.Split(',');
foreach (var column in splitLine)
Console.WriteLine(column);
}
}
If someone can show me what I need to do to get these multi line CSV columns into one line that maintains the formatting (e.g. adds \t or \n where necessary) that would be great. Thanks!
Assuming your source file is valid CSV, variability in the data is really hard to account for. That's all I'll say, but I'll link you to another SO answer if you need convincing that writing your own CSV parser is a horrible task. Reading CSV files using C#
Let's assume you are going to take advantage of an existing CSV reader library. I'll use TextFieldParser from the Microsoft.VisualBasic library as is used in the example answer I linked.
Your task is to read your source file line by line, and validate whether the line is a complete CSV entry on it's own, or if it forms part of a broken line.
If it forms part of a broken line, we need to remember the line and add the next line to it before attempting validation again.
For this we need to know one thing:
What is the expected number of fields each data entry row should have?
int expectedFieldCount = 7;
string brokenLine = "";
using (var streamReader = new StreamReader("results-survey111101.csv"))
{
string line;
while ((line = streamReader.ReadLine()) != null) // read the next line
{
// if the previous line was incomplete, add it to the current line,
// otherwise use the current line
string csvLineData = (brokenLine.Length > 0) ? brokenLine + line : line;
try
{
using (StringReader stringReader = new StringReader(csvLineData ))
using (TextFieldParser parser = new TextFieldParser(stringReader))
{
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields(); // tests if the line is valid csv
if (expectedFieldCount == fields.Length)
{
// do whatever you want with the fields now.
foreach (var field in fields)
{
Console.WriteLine(field);
}
brokenLine = ""; // reset the brokenLine
}
else // it was valid csv, but we don't have the required number of fields yet
{
brokenLine += line + #"\r\n";
break;
}
}
}
}
catch (Exception ex) // the current line is NOT valid csv, update brokenLine
{
brokenLine += (line + #"\r\n");
}
}
}
I am replacing the line breaks that broken lines contain with \r\n literals. You can display these in your resulting one-liner field however you want. But you shouldn't expect to be able to copy paste the result into notepad and see line breaks.
One assumes you have the same number of columns in each record. Therefore in your code where you do your Split you can merely sum the length of splitLine into a running columnsReadCount until they equal the desired columnsPerRecordCount. At that point you have read all the record and can reset the running columnsReadCount back to zero ready for the next record to read.
I have a huge file with ~3 mill rows. Every line contains record like this:
1|2|3|4|5|6|7|8|9
Exactly 8 separators like '|' on every line. I am looking for a way to read this file then extract last '9' number only from every line and store it into another file.
edit:
Ok here is what i done already.
using (StreamReader sr = new StreamReader(filepath))
using (StreamWriter sw = new StreamWriter(filepath1))
{
string line = null;
while ((line = sr.ReadLine()) != null)
sw.WriteLine(line.Split('|')[8]);
}
File.WriteAllLines("filepath", File.ReadAllLines(filepath).Where(l => !string.IsNullOrWhiteSpace(l)));
Read file, extract last digits then write in new file and clear blank lines. Last digit is 10-15 symbols and I want to extract first 6. I continue to read and try some and when I'm done or have some question I'll edit again.
Thanks
Edit 2:
Ok, here I take first 8 digits from the number:
sw.WriteLine(line.Substring(0, Math.Min(line.Length, 8)));
Edit 3:
I have no idea how can I match now every numbers that left in file. I want to match them and to see witch number how many times is in the file.
Any help?
I am looking for a way to read this file then extract last [..] number only from every line and store it into another file.
What part exactly are you having trouble with? In psuedo code, this is what you want:
fileReader = OpenFile("input")
fileWriter = OpenFile("output")
while !fileReader.EndOfFile
line = fileReader.ReadLine
records[] = line.Split('|')
value = records[8]
fileWriter.WriteLine(value)
do
So start implementing it and feel free to ask a question on any specific line you're having trouble with. Each line of code I posted contains enough pointers to figure out the C# code or the terms to do a web search for it.
You don't say where you are stuck. Break the problem down:
Write and run minimal C# program
Read lines from file
Break up one line
write result line to a file
Are you stuck on any one of those? Then ask a specific question about that. This decomposition technique is key to many programming tasks, and indeed complex tasks in general.
You might find the string split capability useful.
Because it's a huge file you must read it line by line!
public IEnumerable ReadFileIterator(String filePath)
{
using (StreamReader streamReader = new StreamReader(filePath, Encoding.Default))
{
String line;
while ((line = streamReader.ReadLine()) != null)
{
yield return line;
}
yield break;
}
}
public void WriteToFile(String inputFilePath, String outputFilePath)
{
using (StreamWriter streamWriter = new StreamWriter(outputFilePath, true, Encoding.Default))
{
foreach (String line in ReadFileIterator(inputFilePath))
{
String[] subStrings = line.Split('|');
streamWriter.WriteLine(subStrings[8]);
}
streamWriter.Flush();
streamWriter.Close();
}
}
using (StreamReader sr = new StreamReader("input"))
using (StreamWriter sw = new StreamWriter("output"))
{
string line = null;
while ((line=sr.ReadLine())!=null)
sw.WriteLine(line.Split('|')[8]);
}
Some pointer to start from: StreamReader.Readline() and String.Split(). There are examples on both pages.
With LINQ you could do a thing like the following to filter the numbers:
var numbers = from l in File.ReadLines(fileName)
let p = l.Split('|')
select p[8];
and then write them into a new file like that:
File.WriteAllText(newFileName, String.Join("\r\n", numbers));
Use String.Split() to get the line inside an array and get the last element and store it into another file. Repeat the process for each line.
Try this...
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader("c:\\test.txt");
while((line = file.ReadLine()) != null)
{
string[] words = s.Split('|');
string value = words [8]
Console.WriteLine (value);
}
file.Close();
This question already has answers here:
Parsing CSV files in C#, with header
(19 answers)
Closed 1 year ago.
I am having string which gives data more like to csv format .
&stamp;field1;field2;field3;field4;&event
10:44:00.6100;0.000;0.000;0.000;0.000; 10:44:00.7100;23.2;0.230;411.2;0.000; 10:44:00.8100;0.000;0.000;1.022;0.000; 10:44:00.9100;8.000;0.000;232.3;0.000;
10:44:01.2100;0.000;0.000;0.000;0.000; 10:44:01.3100;23.2;0.230;411.2;0.000; 10:44:01.5100;0.000;0.000;1.022;0.000; 10:44:01.7100;8.000;0.000;232.3;0.000;
I want to deserialize this data.
this will give you a list of strings "split" at every ; char. you will want to trim and parse the values after. hope this helps
var stringOfData = "0:44:00.6100;0.000;0.000;0.000;0.000; 10:44:00.7100;23.2;0.230;411.2;0.000; 10:44:00.8100;0.000;0.000;1.022;0.000; 10:44:00.9100;8.000;0.000;232.3;0.000;";
List<string> parsed = new List<string>();
parsed.AddRange(stringOfData.Split(';'));
string line = String.Empty;
string[] parts = null;
using (StreamReader sr = new StreamReader(new FileStream(#"C:\yourfile.csv",
FileMode.Open)))
{
while ((line = sr.ReadLine()) != null)
{
parts = line.Split(new [] { ';' });
//Do whatever you want to do with the array of values here
}
}
As for the deserialization part of the question; you would need to specify the kind of format you would want. If you just want a collection of numbers you want to loop through, you could just add every value to a generic List.
If you want a specific format, you could create a class with fields for each of those values and populate a generic list of that class using those values.
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));
}
}
}