0

CSV ファイルに問題があります。この時点で関係のない最初の数行をスキップして、実際のデータが入ってくるところからファイルの処理を開始したいのですが、すべてのヘッダーをスキップする方法はありますか?

これが私のコードです:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace bike
{
    public partial class Form1 : Form
    {
        public Form1()
        {

            InitializeComponent();

        }

        private void button1_Click(object sender, EventArgs e)
        {

            var col1 = new List<string>();
            var col2 = new List<string>();
            var col3 = new List<string>();
            var col4 = new List<string>();

            var Column1 = col1.Select<string, int>(q => Convert.ToInt32(q));
            var Column2 = col2.Select<string, int>(q => Convert.ToInt32(q));
            var Column3 = col3.Select<string, int>(q => Convert.ToInt32(q));
            var Column4 = col4.Select<string, int>(q => Convert.ToInt32(q));



            dataGridView1.Columns.Add("col1", "Heart Rate");
            dataGridView1.Columns.Add("col2", "Speed");
            dataGridView1.Columns.Add("col3", "Power");
            dataGridView1.Columns.Add("col4", "Altitude");



            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
                {

                    int row = 0;
                    string line;

                    bool isInHRData = false;

                    while ((line = sr.ReadLine()) !=null)
                    {
                        if (!isInHRData)
                        {
                            if (line != "[HRData]")
                                continue;
                            isInHRData = true;
                            continue;
                        }

                        else if (line.StartsWith("[") && line.EndsWith("["))
                            break;

                        string[] columns = line.Split('\t');
                        if (columns.Length > 0)
                            col1.Add(columns[0]);
                        if (columns.Length > 1)
                            col2.Add(columns[1]);
                        if (columns.Length > 2)
                            col3.Add(columns[2]);
                        if (columns.Length > 3)
                            col4.Add(columns[3]);



                        /*col1.Add(columns[0]);
                        col2.Add(columns[1]);
                        col3.Add(columns[2]);
                        col4.Add(columns[3]);
                         */

                        dataGridView1.Rows.Add();
                        for (int i = 0; i < columns.Length; i++)
                        {
                            dataGridView1[i, row].Value = columns[i];
                        }
                        row++; 
                    }

                    int maxSpeed = Column2.Max();
                    maxSpeed = maxSpeed / 10;
                    string MaxSpeed = Convert.ToString(maxSpeed);
                    textBox1.Text = MaxSpeed;

                    double aveSpeed = Column2.Average();
                    aveSpeed = aveSpeed / 10;
                    aveSpeed = Math.Round(aveSpeed, 0);
                    string AveSpeed = Convert.ToString(aveSpeed);
                    textBox2.Text = AveSpeed;

                    double aveHeart = Column1.Average();
                    aveHeart = Math.Round(aveHeart, 0);
                    string AveHeart = Convert.ToString(aveHeart);
                    textBox3.Text = AveHeart;

                    int maxHeart = Column1.Max();
                    string MaxHeart = Convert.ToString(maxHeart);
                    textBox4.Text = MaxHeart;

                    int minHeart = Column1.Min();
                    string MinHeart = Convert.ToString(minHeart);
                    textBox5.Text = MinHeart;

                    double avePower = Column3.Average();
                    avePower = Math.Round(avePower, 0);
                    string AvePower = Convert.ToString(avePower);
                    textBox6.Text = AvePower;

                    int maxPower = Column3.Max();
                    string MaxPower = Convert.ToString(maxPower);
                    textBox7.Text = MaxPower;

                    double aveAltitude = Column4.Average();
                    aveAltitude = Math.Round(aveAltitude, 0);
                    string AveAltitude = Convert.ToString(aveAltitude);
                    textBox8.Text = AveAltitude;

                    int maxAltitude = Column4.Max();
                    string MaxAltitude = Convert.ToString(maxAltitude);
                    textBox9.Text = MaxAltitude;


                }
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

CSV ファイルの例 (表示する必要があるのは HRData ビットだけなので、残りはすべて無視します):

[Params]
Version=106
Monitor=34
SMode=111000100
Date=20101110
StartTime=13:47:00.0
Length=02:07:41.7
Interval=5
Upper1=150
Lower1=140
Upper2=0
Lower2=0
Upper3=180
Lower3=177
Timer1=00:00:00.0
Timer2=00:00:00.0
Timer3=00:00:00.0
ActiveLimit=0
MaxHR=195
RestHR=48
StartDelay=0
VO2max=54
Weight=0

[Note]

[IntTimes]
00:01:23.7  139 0   118 139
0   0   0   290 75  69
0   0   0   0   0
0   444 0   70  0   0
0   0   0   0   0   0
00:30:51.4  157 0   145 158
0   0   0   372 133 2
0   0   0   0   0
0   16020   0   90  0   0
0   0   0   0   0   0
01:04:46.0  148 0   146 157
0   0   0   245 118 11
0   0   0   0   0
0   32000   0   80  0   0
0   0   0   0   0   0
01:34:33.7  138 0   144 152
0   0   0   336 116 32
0   0   0   0   0
0   46524   0   70  0   0
0   0   0   0   0   0
02:06:40.4  145 0   144 160
0   0   0   253 130 60
0   0   0   0   0
0   60432   0   60  0   0
0   0   0   0   0   0
02:07:41.7  119 0   129 145
0   0   0   0   75  55
0   0   0   0   0
0   60791   0   60  0   0
0   0   0   0   0   0

[IntNotes]
1   
2   
3   
4   
5   
6   

[ExtraData]

[LapNames]
1   0   
2   0   
3   0   
4   0   
5   0   
6   0   

[Summary-123]
7660    0   820 5995    845 0
195 150 140 48
7660    0   820 5995    845 0
195 0   0   48
0   0   0   0   0   0
195 0   0   48
0   1532

[Summary-TH]
7660    0   7660    0   0   0
195 0   0   48
0   1532

[HRZones]
195
176
156
137
117
98
0
0
0
0
0

[SwapTimes]

[Trip]
607
329
7661
15
70
286
494
4720

[HRData]
91  161 0   64
91  159 0   64
98  225 56  63
105 260 68  63
106 183 70  63
101 52  55  63
104 119 29  63
110 153 32  63
118 161 42  64
124 113 43  65
123 77  38  66
125 189 32  66
129 248 64  66
134 272 73  66
137 271 75  67
137 270 73  67
4

2 に答える 2

3

このコードを試してください:

...
int row = 0;
string line;
bool isInHRData = false;

while ((line = sr.ReadLine()) !=null)
{
    if (!inHRData)
    {
         if (line == "[HRData]")
              isInHRData = true;
         continue;
    } 
    ....

別のセクション AFTER がある場合はHRData、次のコードを追加します。

...
int row = 0;
string line;
bool isInHRData = false;

while ((line = sr.ReadLine()) !=null)
{
    if (!inHRData)
    {
         if (line == "[HRData]")
              isInHRData = true;
         continue;
    } 
    else if (line.StartsWith("[") && line.EndsWith("[")) // This criteria can be mucht better, checking for words, etc. but you in essence this will work.
        break;
    ....

IndexOutOfRangeException の場合:

string[] columns = line.Split('\t');
if (columns.Length > 0)
     col1.Add(columns[0]);
if (columns.Length > 1)
     col2.Add(columns[1]);
if (columns.Length > 2)
     col3.Add(columns[2]);
if (columns.Length > 3)
     col4.Add(columns[3]);
于 2013-04-28T14:15:18.097 に答える
1

残りのコードから発生した他の小さなバグのため、リファクタリングを提案しました。この例はリファクタリングではなく、完全に書き直されています。ユーザー インターフェイスからロジックを分離しました。これは常に良いことです。これにより、ロジックを WPF の Web アプリケーションなどの他の種類のアプリケーションに移行する準備が整います。

このコードは完全に責任の分離に基づいています。

  • HRData: コードの主役であるエンティティ。あなたの基本データ。プロパティはより多くの意味を与えるため、エンティティは int 配列よりも優れています。
  • HRDataExtensions: 計算を行う統計メソッド。
  • HRDataReader: ファイルを読み取り、それを HRData のリストに読み込みます。

この HRData のリストを使用して、UI フォームに入力できます。

public class HRData
{
    public int? HeartRate
    {
        get;
        set;
    }
    public int? Speed
    {
        get;
        set;
    }
    public int? Power
    {
        get;
        set;
    }
    public int? Altitude
    {
        get;
        set;
    }

    public override string ToString()
    {
        return String.Format("Heart rate={0}, Speed={1}, Power={2}, Altitude={3}", HeartRate, Speed, Power, Altitude);
    }
}

public static class HRDataExtensions
{
    static private int? CalculateInt32(this IEnumerable<HRData> data, Func<HRData, int?> valueSelector, Func<IEnumerable<int?>, int?> aggregation)
    {
        List<int?> list = new List<int?>();
        list.AddRange(data.Select(valueSelector));
        return aggregation(list);
    }

    static private int? CalculateDouble(this IEnumerable<HRData> data, Func<HRData, int?> valueSelector, Func<IEnumerable<int?>, double?> aggregation)
    {
        List<int?> list = new List<int?>();
        list.AddRange(data.Select(valueSelector));
        double? result = aggregation(list);
        return (result == null) ? null : (int?)Math.Round(result.Value);
    }

    static public int? MinimumHeartRate(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.HeartRate, Enumerable.Min);
    }

    static public int? MaximumHeartRate(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.HeartRate, Enumerable.Max);
    }

    static public int? AverageHeartRate(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.HeartRate, Enumerable.Average);
    }

    static public int? MinimumSpeed(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Speed, Enumerable.Min);
    }

    static public int? MaximumSpeed(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Speed, Enumerable.Max);
    }

    static public int? AverageSpeed(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.Speed, Enumerable.Average);
    }

    static public int? MinimumPower(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Power, Enumerable.Min);
    }

    static public int? MaximumPower(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Power, Enumerable.Max);
    }

    static public int? AveragePower(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.Power, Enumerable.Average);
    }

    static public int? MinimumAltitude(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Altitude, Enumerable.Min);
    }

    static public int? MaximumAltitude(this IEnumerable<HRData> data)
    {
        return data.CalculateInt32(hr => hr.Altitude, Enumerable.Max);
    }

    static public int? AverageAltitude(this IEnumerable<HRData> data)
    {
        return data.CalculateDouble(hr => hr.Altitude, Enumerable.Average);
    }
}

public static class HRDataReader
{
    static private int? ConvertValue(string[] values, int index)
    {
        if (index >= values.Length)
            return null;
        int value;
        if (int.TryParse(values[index], out value))
            return value;
        return null;
    }

    static public IList<HRData> Read(string fileName)
    {
        if (string.IsNullOrEmpty(fileName))
            throw new ArgumentNullException("fileName");
        using (StreamReader sr = new StreamReader(fileName))
        {
            string line;

            // First: Skip to the correct section.
            while ((line = sr.ReadLine()) != null)
                if (line == "[HRData]")
                    break;

            // Now: Read the HRData
            List<HRData> data = new List<HRData>();
            while ((line = sr.ReadLine()) != null)
            {
                if (line.StartsWith("[") && line.EndsWith("]"))
                    break;
                line = line.Trim().Replace("\t", " "); // Remove all tabs.
                while (line.Contains("  ")) // Remove all duplicate spaces.
                    line = line.Replace("  ", " ");
                string[] values = line.Split(' '); // Split the line up.
                data.Add(new HRData
                {
                    HeartRate = ConvertValue(values, 0),
                    Speed = ConvertValue(values, 1),
                    Power = ConvertValue(values, 2),
                    Altitude = ConvertValue(values, 3)
                });
            }
            return data;
        }
    }
}

編集

これで、次のようにコードを調整できます。

    private void button1_Click(object sender, EventArgs e)
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            dataGridView1.Rows.Clear();
            dataGridView1.Columns.Clear();

            IList<HRData> data = HRDataReader.Read(openFileDialog1.FileName);

            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "HeartRate", HeaderText = "Heart rate", DataPropertyName = "HeartRate" });
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "Speed", HeaderText = "Speed", DataPropertyName = "Speed" });
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "Power", HeaderText = "Power", DataPropertyName = "Power" });
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "Altitude", HeaderText = "Altitude", DataPropertyName = "Altitude" });

            dataGridView1.DataSource = data;

            label1.Text = data.MaximumAltitude().ToString();

            textBox1.Text = data.MaximumSpeed().ToString();
            textBox2.Text = data.AverageSpeed().ToString();
            textBox3.Text = data.AverageHeartRate().ToString();
            textBox4.Text = data.MaximumHeartRate().ToString();
            textBox5.Text = data.MinimumHeartRate().ToString();
            textBox6.Text = data.AveragePower().ToString();
            textBox7.Text = data.MaximumPower().ToString();
            textBox8.Text = data.AverageAltitude().ToString();
            textBox9.Text = data.MaximumAltitude().ToString();
        }
    }
于 2013-04-28T16:29:46.513 に答える