Title: Excel and CSV files II
Slug: excel-and-csv-files-ii
Date: 2008-10-26 12:32:00
Author: Kartones
Lang: en
Tags: Development, C#, CSV
Description: A simple C# method for preparing CSV data for parsing.

<p><a href="https://blog.kartones.net/post/excel-and-csv-files">In a previous recent post</a>, I talked about how to properly export data to respect the CSV format, and allow opening in Excel CSV files with special characters.</p> <p>Once we've given our customer the CSV file, and they've filled it with data, usually comes importing the data back to our application, so... here it is a simple C# implementation of a method that given a string (usually obtained with a simple file <font face="Courier New">ReadLine()</font>) , will prepare it for <font face="Courier New">Split()</font> parsing.</p> <p>First the code:</p> <p><font color="blue">private static string </font><font color="black">PrepareLineForParsing(</font><font color="blue">string </font><font color="black">Data,</font><font color="blue">char </font><font color="black">InputSeparator, </font><font color="blue">string </font><font color="black">OutputSeparator)<br>    {<br>        StringBuilder replacedData</font><font color="blue">;<br>        int </font><font color="black">index </font><font color="blue">= </font><font color="maroon">0</font><font color="blue">;<br>        bool </font><font color="black">flagQuoted </font><font color="blue">= false;<br>        bool </font><font color="black">previousWasQuote </font><font color="blue">= false;<br>    <br>        </font><font color="black">replacedData </font><font color="blue">= new </font><font color="black">StringBuilder(Data.Length)</font><font color="blue">;<br>    <br>        if </font><font color="black">(Data.Length </font><font color="blue">== </font><font color="maroon">0</font><font color="black">)<br>            </font><font color="blue">return </font><font color="black">String.Empty</font><font color="blue">;<br>        <br>        for </font><font color="black">(index</font><font color="blue">=</font><font color="maroon">0</font><font color="blue">; </font><font color="black">index &lt; Data.Length</font><font color="blue">; </font><font color="black">index++)<br>        {<br>            </font><font color="blue">if </font><font color="black">(Data[index] </font><font color="blue">== </font><font color="black">InputSeparator)<br>            {<br>                </font><font color="darkgreen">//If we're quoting, ignore separator <br>                </font><font color="blue">if </font><font color="black">(!flagQuoted)<br>                    replacedData.Append(OutputSeparator)</font><font color="blue">;<br>                else<br>                    </font><font color="black">replacedData.Append(Data[index])</font><font color="blue">;<br>                </font><font color="black">previousWasQuote </font><font color="blue">= false;<br>            </font><font color="black">}<br>            </font><font color="blue">else<br>            </font><font color="black">{<br>                </font><font color="blue">if </font><font color="black">(Data[index] </font><font color="blue">== </font><font color="#808080">'\"'</font><font color="black">)<br>                {<br>                    </font><font color="darkgreen">//Double quote with something inside means skip the block<br>                    //Only write a single double quote if we're inside a double quoted block and have '""'<br>                    </font><font color="black">flagQuoted </font><font color="blue">= </font><font color="black">!flagQuoted</font><font color="blue">;                    <br>                    if </font><font color="black">(previousWasQuote)<br>                    {<br>                        previousWasQuote </font><font color="blue">= false;<br>                        if </font><font color="black">(flagQuoted)<br>                            replacedData.Append(</font><font color="#808080">"\""</font><font color="black">)</font><font color="blue">;<br>                    </font><font color="black">}<br>                    </font><font color="blue">else<br>                        </font><font color="black">previousWasQuote </font><font color="blue">= true    ;<br>                </font><font color="black">}<br>                </font><font color="blue">else<br>                </font><font color="black">{<br>                    replacedData.Append(Data[index])</font><font color="blue">;<br>                    </font><font color="black">previousWasQuote </font><font color="blue">= false;<br>                </font><font color="black">}<br>            }<br>        }<br>    <br>        </font><font color="blue">return </font><font color="black">replacedData.ToString()</font><font color="blue">;<br>    </font><font color="black">}</font></p> <p> </p> <p>Then the notes... Of which there are none as the code is self-explaining... just go character by character detecting when we have a new field (with or without double quotes) and when we have two double quotes (meaning a single double quote as result).</p>
