プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

C#でTextファイルへの入出力

例としてHearth Loggerを作ります。
Form1は以下のようなものを作りました。

仕様としては、
・入力は日付、体重、体脂肪率
・プログラムを起動したら、日付は今日の日付を表示。ただし、手入力で変更可能
・OKを押下でファイルに記録。
・OKを押したときグラフCheckboxがONならグラフを表示

f:id:s51517765:20170329203915j:plain


まず、ファイル入出力を扱うので、以下を追加します。

using System.IO;

OKボタンを押下したときに、日付、体重、体脂肪を「カンマ」区切りでtxtもしくはcsvに取り込みます。
日付は後述で自動的に今日の日付を入れるようにしてありますが、体重と体脂肪が空欄の時は追記をスキップします。
チェックボックスがCheckedのときは、グラフを表示します。
グラフの表示にCheckboxの判断を掛け合わせていますが、グラフのインスタンス生成のところはよくわかってないので適切かどうか…。

 private void button1_Click(object sender, EventArgs e)
        {
            double weight;
            double fat;
            if (double.TryParse(textBoxWeight.Text, out weight) == true &&
                double.TryParse(textBoxFat.Text, out fat)==true)
            {
                using (StreamWriter writer = new StreamWriter("data.txt", true)) 
                      //書き込む先のファイル名は"data.text"
                {
                    writer.Write(textboxDate.Text); //textboxの内容を書き込む
                    writer.Write(",");          //任意(ここではカンマ)のTextを書き込む。
                    writer.Write(textBoxWeight.Text);
                    writer.Write(",");
                    writer.WriteLine(textBoxFat.Text);
                    writer.Flush();
                    textBoxWeight.Text = "";  //入力欄であるtextboxをクリア
                    textBoxFat.Text = "";
                }
            }

            Graph Form2 = new Graph();   //グラフのインスタンス生成
            if (checkBoxGraph.Checked == true)  //Checkbox判断
            {
                if (Form2.ShowDialog() == DialogResult.OK) //OKボタンが押されたら
                {

                }
            }

            Form2.Dispose();

        }

日付は今日の日付を取得し、年月日の形式で表示します。

     private void Form1_Load(object sender, EventArgs e)
        {   //Form1が開いたときの動作
            DateTime dt = DateTime.Now; //dtに今日の日付(と現在時刻)
            textboxDate.Text = dt.ToString("yyyy-MM-dd");  //textboxに文字列として"dt"をyyyy-mm-ddの日付形式で
        }

ここまでが、Form1。

ここからForm2。
Form2が読み込まれたときの動作。
始めにまとめて変数を定義しています。
Tryの中でファイルを開いて、日付、体重、体脂肪率にわけて配列に読み込むようにしています。
ここで、Tryは処理に例外が発生した場合、CatchにすすみErrorを出します。
Try,Catchの構文で、予期せぬErrorで止まってしまうのを防ぎます。

   private void Form2_Load(object sender, EventArgs e)
        {
            int n = 1;
            int no = 0;
            int Data_Count=4;
            int Array_Length = 400;
            string[] date = new string[Array_Length];
            string[] Weight_text= new string[Array_Length];
            double[] Weight = new double[Array_Length];
            string[] Fat_text=new string[Array_Length];
            double[] Fat = new double[Array_Length];
            DateTime[] date_style = new DateTime[Array_Length];

try
            { //csvファイルを開いて、日付、体重、体脂肪率にわけて配列に読み込む

                string[] StrArryData = new string[3]; // 1行分のデータを格納する
                using (var sr = new System.IO.StreamReader(@"data.txt")) //読み込むファイル名
                {

                    while (!sr.EndOfStream) //ファイルエンドまで
                    {
                        var line = sr.ReadLine();    // ファイルから一行読み込む
                        StrArryData = line.Split(','); //一行を区切る

                        foreach (string value in StrArryData) //strArrayDatsをStringとして、そのすべてに対して
                        {

           //Data3つごとに分けて配列に格納
                            if (n % 3 == 1)
                            {
                                date[no] = value;
                                DateTime.TryParse(date[no], out date_style[no]); //textをDateTime型に
                            }
                            else if (n % 3 == 2)
                            {
                                Weight_text[no] = value;
                                double.TryParse(Weight_text[no], out Weight[no]); //Textを数値に型変換
                            }
                            else if (n % 3 == 0)
                            {
                                Fat_text[no] = value;
                                double.TryParse(Fat_text[no], out Fat[no]);
                                no++;
                            }
                            n++;
                        }
                        Data_Count = no;
                    }
                }
            }
           catch (System.Exception ee)
            {
                MessageBox.Show("Error");
                // ファイルを開くのに失敗したとき
            }

次に、グラフの表示内容

           // 1.Seriesの追加
            Chart1.Series.Clear();
            Chart1.Series.Add("Weight (kg)");
            Chart1.Series.Add("Body fat (%)");
            

            // 2.グラフのタイプの設定
              Chart1.Series["Weight (kg)"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
              Chart1.Series["Weight (kg)"].MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Diamond;
              Chart1.Series["Body fat (%)"].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
              Chart1.Series["Body fat (%)"].MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Diamond;
          
            // 3.座標の入力
            for (no = 0; no < Data_Count; no++)
            {
                Chart1.Series["Weight (kg)"].Points.AddXY(date_style[no],Weight[no]);
                    Chart1.Series["Body fat (%)"].Points.AddXY(date_style[no], Fat[no]);
               }

グラフはこのページを参考にした…というより丸写しに近い。
whoopsidaisies.hatenablog.com

f:id:s51517765:20170329220510j:plain