简体   繁体   中英

Reading only numbers in CSV file C#

I have a CSV file with values:

,Vb(M),Ke23(M^-1),
AAA,3.91E-06,2.21E+06
BBB,6.65E-03,3.50E+03
CCC,0.213,1503.759398
DDD,1.37E+00,0.00E+00

I want to read the file and store only the number values in the CSV file.

I would like to do this by manipulating the code that is featured here: http://www.codeproject.com/Articles/415732/Reading-and-Writing-CSV-Files-in-Csharp

Or is there an easier way to just read and store the numbers?

It's fairly simple, just loop over the lines of the file splitting on commas, then loop over the tokens using TryParse something like this should work;

List<double> numbers = new List<double>();
double buffer = 0;
while (string line = reader.ReadLine() != null)
{
      string[] tokens = line.Split(',');
      foreach (string s in tokens)
      {
          if (double.TryParse(s, out buffer))
              numbers.Add(buffer);
      }
}

// to print the values with iteration
foreach (double d in numbers)
     Console.WriteLine(d.ToString());

// to print with LINQ
numbers.Select(x => Console.WriteLine(x.ToString()));

Disclaimer: I wrote the code in browser so it hasn't been compiled or tested. Some minor adjustments might be necessary but that's pretty much the simplest way to do it.

A LINQ solution:

var numbers = File.ReadLines("file.txt")
    .SelectMany(line => line.Split(','))
    .Select(token =>
    {
        double value;
        return double.TryParse(token, out value) ? (double?)value : null;
    })
    .Where(value => value != null)
    .Select(value => value.Value)
    .ToList();

Try FileHelpers for parsing CSV files. It can easily give you strongly typed access to your file so you can easily pick out the number values as simple properties.

Here is a quick example of parsing your data with Filehelpers, to get the second column.

 static void Main(string[] args)
    {
        var engine = new FileHelperEngine(typeof(MyRecord));
        MyRecord[] myRecords = engine.ReadFile("data.csv") as MyRecord[];
        var numbers = myRecords.Select(x => x.ColumnB);
        foreach (var number in numbers)
        {
            Console.WriteLine(number);
        }
        Console.ReadLine();

    }

    [DelimitedRecord(",")] 
    public class MyRecord
    {
        public string ColumnA;

        [FieldConverter(typeof(ScientificNotationConverter))] 
        public double ColumnB;

        [FieldConverter(typeof(ScientificNotationConverter))] 
        public double ColumnC;
    }

    public class ScientificNotationConverter : ConverterBase
    {
        public override object StringToField(string @from)
        {
            return Double.Parse(@from, System.Globalization.NumberStyles.Float);
        }
    }

If I understand your question correctly, you could try something like this.

note: this assumes a perfectly formed CSV file such as you provided. you need to include error checking otherwise it is sure to fail at some point

string[] lines = File.ReadAllLines("MyCsvFile");
Dictionary<string, double> parsedCsv = new Dictionary<string,double>();

// Read the first line
string col1 = "", col2 = "";
if(lines.Length > 0)
{
    string[] tokens = lines.Split(',');
    col1 = tokens[1];
    col2 = tokens[2];
}

for(int i = 1; i < lines.length; i++)
{
    string[] tokens = lines.Split(',');
    string varName1 = tokens[0] + "." + col1;
    string varName2 = tokens[0] + "." + col2;
    double value = double.Parse(tokens[1]);
    parsedCsv.Add(varName1, value);
    value = double.Parse(tokens[2]);
    parsedCsv.Add(varname2, value);
}

Now you can access a value form the dictionary like so.

double AAA1 = parsedCsv["AAA.Vb(M)"];
double AAA2 = parsed Csv["AAA.Ke23(M^-1)"]

and so on.

Keep in mind I have NO error checking. I'm only showing a way to associate the parsed in values with some variable association at runtime via a Dictionary<>. I didn't include how to use the linked CsvReader library. If you have questions specifically about how to use it I would ask another question.

Here's the answer i was able to get from @evanmcdonnal's answer:

        StreamReader reader = new StreamReader(@"F:\BP1.csv");
        List<double> numbers = new List<double>();
        double buffer = 0;

        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
            string[] tokens = line.Split(',');

            foreach (string s in tokens)
            {
                if (double.TryParse(s, out buffer))
                    numbers.Add(buffer);
            }
        }

        foreach (double d in numbers)
            Console.WriteLine(d.ToString());
        reader.Close();

output: 3.91E-06 2210000 0.00665 3500 0.213 1503.759 1.37 0

Gives what i was looking for. Thanks everyone!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM