I am reading a csv file which has following data format
14-Sep-12 ALUMINI 31-Dec-12 117.65 119.25 117.65 118.9 116.75 36
14-Sep-12 ALUMINI 30-Nov-12 116.95 118.65 116.8 118.4 116.5 252
14-Sep-12 ALUMINI 31-Oct-12 116.45 118.15 116.05 117.85 116.05 2802
I am reading this data with following code
List<string> sc = new List<string>();
filepath = "abc.csv" ;
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
StreamReader sr = new StreamReader(fs);
if (fs != null)
{
while ((oneLine = sr.ReadLine()) != null)
{
sc.Add(oneLine);
}
sr.Close();
// Now writing above data in some file , fo and fout are already declared
fo = new FileStream("tempd.txt", FileMode.Append, FileAccess.Write);
fout = new StreamWriter(fo);
foreach (string str in sc)
{
// i am using ' ' as one of my splitter character
char[] splitter = { ' ', ',', '\t' };
string[] sa1 = str.Split(splitter);
string wline = sa1[0] + "," + sa1[1] + "," + sa1[5] + "," + sa1[6] + "," + sa1[7] ;
fout.WriteLine(wline);
}
fout.Close();
}
My biggest problem is first column of of data is 14-Sep-2012 has been changed to 14 Sep 2012 (- is missing). Which is creating problem in my rest of application.
Is there any way by which I can convert date format while reading and writing file, I want to store this date 14-Sep-2012 as 2012-9-14.
I think this is the answer you are looking for.
DateTime d = Convert.ToDateTime(sa1[0]);
string wline = d.ToString("yyyy-MM-dd") + "," + sa1[1] + "," + sa1[5] + "," + sa1[6] + "," + sa1[7];
Your question doesn't make a lot of sense, so I'm going to make some assumptions here. First, you say that it's a CSV file. CSV stands for Comma Separated Values, but when you show the example - I see no commas at all. Am I right in thinking you have opened the CSV in Microsoft Excel and copied from there into your post?
If so, I then I would ask you to open your original CSV file in Notepad (or another text editor) instead. You will likely see then that your original data does not actually have the dashes.
Basically, when you provide a date in as 14 Sep 12 in your CSV file - Excel recognizes that this is a date, but then it formats it with its own default date format, which makes it look like 14-Sep-12 in Excel.
Another thing - you are reading the entire file into a list of strings, and then outputting the entire list back to a new file reformatted. Rather than load all of this in memory, why not just operate one line at a time? Open both your input and output files, read a line from input, manipulate it, and write it to output. Then loop to the next line and close both files when done. You will find this uses much less memory and generally runs faster.
If you want to reformat the dates, that's easy. Just parse the string into a date. Then control the output of your date with a string formatter in .ToString(). I belive Geethanga's answer shows this well, but Date.Parse() is usually preferred over Convert.ToDateTime().
Related
I want to extract each string between the first "" for each row and create a text file with it.
sample CSV:
number,season,episode,airdate,title,tvmaze link
1,1,1,13 Sep 05,"Pilot","https://www.tvmaze.com/episodes/991/supernatural-1x01-pilot"
2,1,2,20 Sep 05,"Wendigo","https://www.tvmaze.com/episodes/992/supernatural-1x02-wendigo"
3,1,3,27 Sep 05,"Dead in the Water","https://www.tvmaze.com/episodes/993/supernatural-1x03-dead-in-the-water"
4,1,4,04 Oct 05,"Phantom Traveler","https://www.tvmaze.com/episodes/994/supernatural-1x04-phantom-traveler"
5,1,5,11 Oct 05,"Bloody Mary","https://www.tvmaze.com/episodes/995/supernatural-1x05-bloody-mary"
Final result .txt file:
Pilot
Wendigo
Dead in the Water
Phantom Traveler
Bloody Mary
my function:
private void GetEpisodeNamesFromCSV()
{
using (StreamReader sr = new StreamReader(AppDir + "\\list.csv"))
{
string strResult = sr.ReadToEnd();
string[] result = strResult.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
File.WriteAllLines(AppDir + "\\list_generated_" + ShowTitel + ".txt", result);
}
}
I can't figure out how to properly Split the stream reader object, to only get the names on each Line. I'm very new to programming, and this site helped me immensely! But this problem is specific, and I couldn't find the answer myself. I appreciate any help.
EDIT:
I went with the csvHelper solution suggested by #Jesús López:
// Create a List
List<string> episodeNames = new List<string>();
// Make sure ther are no empty lines in the csv file
var lines = File.ReadAllLines(AppDir + "\\list.csv").Where(arg => !string.IsNullOrWhiteSpace(arg));
File.WriteAllLines(AppDir + "\\list.csv", lines);
// Open the file stream
var streamReader = File.OpenText(AppDir + "\\list.csv");
var csv = new CsvReader(streamReader, CultureInfo.InvariantCulture);
// Read the File
csv.Read();
// Read the Header
csv.ReadHeader();
// Create a string array with Header
string[] header = csv.Context.Reader.HeaderRecord;
// Select the column and get the Index
var columnExtracted = "title";
int extractedIndex = Array.IndexOf(header, columnExtracted);
// Read the file and fill the List
while (csv.Read())
{
string[] row = csv.Context.Reader.Parser.Record;
string column = row[extractedIndex];
episodeNames.Add(column);
}
// Convert the List to a string array
string[] result = episodeNames.ToArray();
//write the array to a text file
File.WriteAllLines(AppDir + "\\list.txt", result);
This is not so much help on StreamReader as it is on strings
If you are confident of the file layout and format as shown (and that it will be consistent), try this quick-and-dirty in a Console app
:
var line = sr.ReadLine();
while (line != null)
{
if (line.Trim() == string.Empty) continue;
var lineEntries = line.Split(',', StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(lineEntries[4].Trim('"'));
line = sr.ReadLine();
}
Note that I offer this because of your statement "I am very new to programming" to show off methods string.Split() .Trim() (and check out .Join()) and how easy they make the basic logic of what you want to achieve.
Using a proper CSV reader is the best idea for a robust solution (plus data-integrity checking, exception handling etc), but there is a reciprocal danger of over-engineering, so if this code displays what you want/expect for a once-off learning experience, then go ahead and implement;-)
I'm having two problems with reading my .csv file with streamreader. What I'm trying to do is get the values, put them into variables which I'll be using later on, inputting the values into a browser via Selenium.
Here's my code (the Console.Writeline at the end is just for debugging):
string[] read;
char[] seperators = { ';' };
StreamReader sr = new StreamReader(#"C:\filename.csv", Encoding.Default, true);
string data = sr.ReadLine();
while((data = sr.ReadLine()) != null)
{
read = data.Split(seperators);
string cpr = read[0];
string ydelsesKode = read[1];
string startDato = read[3];
string stopDato = read[4];
string leverandoer = read[5];
string leverandoerAdd = read[6];
Console.WriteLine(cpr + " " + ydelsesKode + " " + startDato + " " + stopDato + " " + leverandoer + " " + leverandoerAdd);
}
The code in and of itself works just fine - but I have two problems:
The file has values in Danish, which means I get åøæ, but they're showing up as '?' in console. In notepad those characters look fine.
Blank values also show up as '?'. Is there any way I can turn them into a blank space so Selenium won't get "confused"?
Sample output:
1372 1.1 01-10-2013 01-10-2013 Bakkev?nget - dagcenter ?
Bakkev?nget should be Bakkevænget and the final '?' should be blank (or rather, a bank space).
"Fixed" it by going with tab delimited unicode .txt file instead of .csv. For some reason my version of excel doesn't have the option to save in unicode .csv...
Don't quite understand the problem of "rolling my own" parser, but maybe someday someone will take the time to explain it to me better. Still new-ish at this c# stuff...
Hi my application basically reads a CSV file which will always have the same format and I need the application to create a CSV file with different formatting. Reading and writing CSV file is not the issue, however the problem I am having is getting the amounts value as these are formatted with a , in the csv file (ex: 4, 500). Having said that these are being split when writing to csv file.
Ex: From the below, how can I get the full numbers .i.e. 2241.84 & 1072809.33
line = "\"02 MAY 18\",\"TTEWTWTE\",\"GRHGWHWH\",\"02 MAY 18\",\"2,241.84\",\"\",\"1,072,809.33\""
This is how I am reading from CSV file.
openFileDialog1.ShowDialog();
var reader = new StreamReader(File.OpenRead(openFileDialog1.FileName));
List<string> searchList = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
searchList.Add(line);
}
So far I have tried to use the below which gets you \"2,241.84\" which is correct but when writing to csv file I am only getting 2
searchList[2].Split(',')[1].Replace("\"", "")
Let me visualize contents in another way:
"
\"02 MAY 18\",
\"TTEWTWTE\",
\"GRHGWHWH\",
\"02 MAY 18\",
\"2,241.84\",
\"\",
\"1,072,809.33\"
"
It seems that your separator is \", rather than ,. Change searchList[2].Split(',')[1].Replace("\"", "") to searchList[1].Split(new string[] { "\",\"" }, StringSplitOptions.None).
In your case you can use this:
var result = searchList[2].Split(new string[] { "\",\"" }, StringSplitOptions.None)[4].Replace("\"", "");
Split your string with "," separator, instead of ,.
I don't know why you are using static numbers for indexes, but I will assume it's for test purposes.
I've created multiple binary files, each containing 2 strings, 2 chars, 1 double, and 1 int. The data, when read, is
Fokker DR 1
Germany
D
A
1000.0
13
And the binary file reads as follows:
I am trying to parse the dat file into an array so I can label each data type with the appropriate name such as
Name: Fokker DR 1
Country: Germany
Attack Mode: D
Turn Mode: A
etc.
But I am having trouble because, when trying to use StreamReader and split the binary file at every instance of a whitespace, I run into problems due to the fact that the Name (Fokker DR 1) contains multiple spaces that should not be split.
Here is my code for my attempted split:
if (file.Contains("plane1"))
{
StreamReader reader = new StreamReader("plane1.dat");
string line;
while ((line = reader.ReadLine()) != null)
{
string[] data = line.Split(' ');
bin.ReadBinary("plane1.dat");
Console.WriteLine("Name: " + data[0]);
Console.WriteLine("Country: " + data[1]);
Console.WriteLine("Turn Mode: " + data[2]);
Console.WriteLine("Attack Mode: " + data[3]);
Console.WriteLine("Cost: " + data[4]);
Console.WriteLine("Max Damage: " + data[5]);
}
}
Is there any sort of way to split at every instance of a different data type or is there another way to go about labeling the data in my binary file??
The BinaryFormatter will not handle that file format. Given the small size and straight forward specs some ustom read logic should do the trick.
If you open your file with a BinaryReader you can decide for your self what to do with the next byte or bytes you're about to read. If the format of the file is not to complex this is easy doable. Based on your specs I created this code to read your file:
using(var br = new BinaryReader(
File.Open(#"c:\tmp\plane.dat", FileMode.Open),
Encoding.ASCII))
{
while(br.BaseStream.Position < br.BaseStream.Length)
{
var name = br.ReadString();
var country = br.ReadString();
var turnmode = br.ReadChar();
var attackmode = br.ReadChar();
var cost = br.ReadDouble();
var maxdamage = br.ReadInt32();
// you can use above vars what ever you need to do
// with them, writing to the console or adding to
// a list for example
// Planes.Add(new Plane {Name = name});
}
}
In my test a file I created matched your binary format. As you didn't show where the next record start you might find that you need to do an extra read, for example with a ReadByte but that depends on your actual structure.
I'm using an ASP.NET application which exports my clients data to CSV, I need my clients Phone number to be with the leading Zero.
I need the phone numbers to be without "-" and without quotations, and due to the nature of my application I cannot use 3rd party products such as EPPLUS.
I've tried to put a space and let the CSV "understand" that I need the phone number as text , but that doesn't seem right.
I would like to know how to make the excel include the leading zero , without using 3rd party products.
Thanks
Change the data that is saved in the csv with the following format:
="00023423"
CSV example:
David,Sooo,="00023423",World
This will show 00023423 in excel and not 23423.
public void CreatingCsvFiles(Client client)
{
string filePath = "Your path of the location" + "filename.csv";
if (!File.Exists(filePath))
{
File.Create(filePath).Close();
}
string delimiter = ",";
string[][] output = new string[][]{
new string[]{ "=\"" + client.phone + "\"", client.name }
};
int length = output.GetLength(0);
StringBuilder sb = new StringBuilder();
for (int index = 0; index < length; index++)
sb.AppendLine(string.Join(delimiter, output[index]));
File.AppendAllText(filePath, sb.ToString());
}
Inspired from http://softwaretipz.com/c-sharp-code-to-create-a-csv-file-and-write-data-into-it/
The important part :
"=\"" + client.phone + "\"", client.name
If the phone number is an int, of course you add .toString().
Print phone number to CSV with prepended ' (single quote), so it looks like:
"Some Name","'0000121212"
Excel should treat this 0000121212 as string then.
I believe converting the number into a formula like the accepted answer might not be a helpful solution for all.
The alternate solution I went with is to just add a tab space before the integer value.
Example:
Taking phoneNumber as a string variable which contains our int value
Solution:
"\t" + phoneNumber
If you know already how much numbers has to be inside phone you can do like this
phoneNumber.ToString("000000000000")
In this example I consider that phoneNumber is an int and required length of numbers is 12.