東京工芸大学 工学部  電子機械学科 2年 後期 

応用プログラミング 第6回
 2017.10.31
藤木 文彦


http://fujiki.tv/t-kougei/ouyouprog/

fujiki.kougei@gmail.com  
 ■ 1   ■ 2   ■ 3   ■ 4  ■5   ■ 6   ■ 77   ■ 88   ■  9   ■ 10   ■ 11  ■ 12    ■ 13   ■ 14   ■ 15   ■ 00   ■ 00   ■ 00

インデックスに戻る



先週の課題のやり残しがある人は、
今日の課題を全部行ってから、時間がある限り先週のやり残しをやってください。

 1.グラフを描く
  プログラム中にデータを配列で入れておく方法


 "Project601"
 という名前でプロジェクトを開始します

 初めに今日の演習で作るプログラムの内容と、完成(間近の)イメージを掲げておきます。







private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.pictureBox1.CreateGraphics();
int width = this.pictureBox1.Width - 1;
int height = this.pictureBox1.Height - 1;
g.DrawRectangle(Pens.Black, 0, 0, width, height);

int[] data_a;
int datamax = 21;
data_a = new int[21]{
0,110,20,29,41,53,58,72,80,91,99,110,
121,
129,
143,
149,
160,
171,
183,
189,
199};
Pen deepPinkPen = new Pen(Color.DeepPink, 2);

for (int i = 0; i < datamax; i++)
{
g.DrawEllipse(deepPinkPen, i * 10, data_a[i], 5, 5);
}

 【演習問題1】 

 Project601.cs ファイルをメールに添付して送りなさい。

 また、実行画面のコピーを提出しなさい。


 ところで、上記のプログラムでは、データの数がいくつあるか数えて、配列の大きさをあらかじめ決めて宣言していましたが、これは面倒です。

 データ数がいくつか数えなくても、好きなだけ並べたら、自動的にその数を数えて合わせてくれるようにできたら便利ですよね。
 そのような時には、次のように、します。
 上記のプログラムの該当部分を、なん箇所か、書き直します。
 以下を参考に自分で書き直し、データをいくつか追加してみましょう。

 これを、課題「1−2」として、出力をプリントして提出してもらいます。
 適当なデータを10個ほど追加したものを作成し、画面をプリントして提出しなさい。

  int datamax;
data_a = new int[]{

 中略

};

datamax = data_a.Length;

for (int i = 0; i < datamax; i++)

 2.データを画面から入力する方法


 前のプロジェクトを閉じて、新規プロジェクト

Project602" を作成します。

 次のような画面をデザインしてください。

 見えにくいかもしれませんが、 X の下に、textBox が5つ、Y の下にも同様に5つあります。

 ここに、5つの点の(x、y) 座標を入れていく予定です。

 x0  y0 
 x1  y1
 x2  y2
 x3  y3
 x4  y4

のように並ぶようにします。


 このままだと、10個も textBox があり、番号が何を意味しているのか、分かりにくいので、それぞれの textBox に、別の名前を付けていきます。

 いままでは、黙ってつけられていた、 textBox1 などをそのまま使っていましたが、その名前を x0 などに変更します。
 プロパティの

(Name)

の欄を次のように書き換えます。






以下、x0〜x4、 y0〜y4 を入れるように、1つずつ textBox の名前を変えていきます。
面倒ですが、こうすることで、プログラム中で、この 名前(x1など)が使えますので、あとあとのプログラムが楽で、わかりやすくなります。


 この先プログラムを入力しますが、その前に、完成イメージを掲げておきましょう。
 下のように、入力した (x、y) の5か所にドット(小円)を描くものです。



 次にプログラムですが、以下のように、配列 x[5]  y[5]  を用いています。
 見てもらうとわかるように、同じことの繰り返しで、少々無駄だらけのプログラムになっていますが、もっとうまい作り方は、今後順を追って説明していきます。




  private void button1_Click(object sender, EventArgs e)
{
int[] x,y;
x=new int[5];
y=new int[5];

x[0] = int.Parse(x0.Text);
x[1] = int.Parse(x1.Text);
x[2] = int.Parse(x2.Text);
x[3] = int.Parse(x3.Text);
x[4] = int.Parse(x4.Text);

y[0] = int.Parse(y0.Text);
y[1] = int.Parse(y1.Text);
y[2] = int.Parse(y2.Text);
y[3] = int.Parse(y3.Text);
y[4] = int.Parse(y4.Text);

Graphics g = this.pictureBox1.CreateGraphics();
Pen deepPinkPen = new Pen(Color.DeepPink, 2);

g.Clear(Color.LightPink);

for (int i = 0; i < 5; i++)
{
g.DrawEllipse(deepPinkPen, x[i], y[i], 5, 5);
}

}


 データを入力後、描画ボタンを押してください。

 プログラムを簡単にするために、初期値設定や、データのエラーチェックは行っていません。
 データを入力せずにボタンを押したり、数値以外を入力するとエラーになります。

 データが入力されなくてもエラーにならないようにするにはどうしたらよいでしょうか?
 また、データが数値でなかった時にエラーを返すようにするにはどうしたらよいでしょうか?
 先々週のページを参照に、初期値の設定と、エラー入力のチェックを行ってみなさい。

 なお、1度描画したあと、いくつかの入力を変更して再描画することもできます。
 この時前に入力した点が消えますが、これは、画面クリアコマンド、

g.Clear(Color.LightPink);

 が入っているためです。
 これがないとどうなるか、実験してみましょう。

 【演習問題2】 

 Project602.cs ファイルをメールに添付して送りなさい。

 また、実行画面のコピーを提出しなさい。


 3.ファイルの内容を表示する。(テキストファイル)
System.IO.StreamReader()  他
textFile.ReadLine();



"Project603"
 を作成します。
 初めに今日の演習で作るプログラムの内容と、完成(間近の)イメージを掲げておきます。




 それでは、まず、次のように最初の画面を用意してください。

 下の大きな箱は、 PictureBox ではなく、
 
listBox

 というのを選びますから注意してください。





 次にファイルのパス名を入れたら、次のように、ファイルの内容を表示するプログラムとするプログラムを作成します。
 ファイルをオープンする部分を含めて、次のように書きます。





private void button1_Click(object sender, EventArgs e)
{

string filePath = this.textBox1.Text;
System.IO.StreamReader textFile;
string line;

if (System.IO.File.Exists(filePath) == false)
{
MessageBox.Show("ファイルが見つかりません", "エラー");
return;
}

this.listBox1.Items.Clear();

textFile = new System.IO.StreamReader(
filePath, System.Text.Encoding.Default);
line = textFile.ReadLine();
while (line != null)
{
this.listBox1.Items.Add(line);
line = textFile.ReadLine();
}
textFile.Close();

}


 実行する前に読み込むファイルを作成しておかなければなりません。

 TeraPad など、適当なエディタを使って、次のように、数行のテキストファイルを作成して保存しておきます。

 (内容はなんでもよい)

test001
test002
日本語003
これでもか004 


 保存する場所は、

  Z ドライブに 「 cdata 」 フォルダを作り、
 そこに、 「text.txt」 という名前のファイルとして作成しなさい。


 作成後、プログラムを実行し、ファイル名のところに、このファイル名を、フォルダを正しく指定して書き込みます。

 " Z:\cdata\text.txt "

 そして、「表示」ボタンをおすと、ファイル名が正しく入力されていれば、下のように表示されるはずです。
(下の例は、私のPCの個人フォルダの都合上、 C: ドライブとなっているが、みなさんは、 Z: ドライブとしてください。)




 ファイルが見つからない原因の多くが、ファイルの名前の間違いです。
 ファイル名が、  "text.txt.txt" などのようになっている場合がかなりありますので、このような場合は、名前を変更してください。


 ところで、このプログラムでは、1行ファイルから読み込んで表示し、次の行を読み込んで、最後(nullが読み込まれる)でなければ繰り返すような処理をしています。
 そのために、while の繰り返しの前に、1行読み込んでおいてから、 while をはじめ、出力後に、もう1行読み込む、という、2度手間のようなプログラムになっています。上の例の、



のところです。
 ここは、読み込みの命令

textFile.ReadLine();

 が2か所で使われていますので、あまりきれいなプログラムではありません。

そこで、次のようにすることで、プログラムをきれいにすることができます。



 ここで、

while ((line = textFile.ReadLine()) != null)

の行は、1つの命令で、
  
ファイルから1行読み込み 変数 line に代入する。
  その line の中身が null であるかどうか、比較する

という「操作と比較」を同時に行っていることに注意してください。

 このような書き方は、C言語系列の言語に特有の物であり、便利な方法なのですが、他の言語では、使えないものが多くありますので注意が必要です。

 上記のように、プログラムを書き直して実行してみなさい。



 上記のように出力するためには、プログラムの出力部分を次のように書き換えます。

this.listBox1.Items.Add( num.ToString() + ":\t" + line);

 ここで、"num" というのが、出力する行数の数値です。
 ですから、どこかに、
  int num=0;
 を入れ、どこかに、
  num++;
 を入れないといけませんね。

 この部分をどこに入れると上のような出力になるのか。
 これは、そのまま書いてしまうと勉強にならないので、自分で考えて入れてください。
 先ほどから変更している場所の近くを少し変えるだけですから、それほど難しくないはずですので考えてみてください。

 この結果の出力(上の図のようになる。行数表示が正しければ、本文の内容や行数は適当でよい。)をプリントして提出します。

 【演習問題3】 

 Project603.cs ファイルをメールに添付して送りなさい。

 また、実行画面のコピーを提出しなさい。

 4.ファイル名選択ボックスの使用
"OpenFileDialog"


 前のプログラムでは、ファイル名をフォルダまで含めて正しく指定しないとなりませんでした。
 これは面倒です。
 普通のソフトにあるように、ファイル名の一覧が出て中から選択できるようにしたいですよね。
 ここでは、その方法を学習します。

 今までの作業結果を保存し、新しいプロジェクトを開始します。
 なお、前のプロジェクトを終了するときに、普通に終了する前に必ず、 cs ファイルも、保存しておいてください。次のプロジェクトで使います。

 では、次のような新規プロジェクトを作成します。

 プロジェクト名   
Project604
 csファイル名   FileList1
としておきましょう。


 それでは、いつものように、画面をデザインします。
 これはもう、簡単ですね。
 ファイル名入力の部分が、 ボタンに変わっていますから注意してください。ボタンの名前が長いので、少し横幅を広げましょう。




 次に、ファイルリストを表示するツールとして、ツールボックスから、
"OpenFileDialog"
 を選んで、画面上の適当な位置に配置します。

 しかし、このとき、今までのように、画面のデザインの中に配置されず、下に分けて置かれます。
なんか、変な感じがするのですが、これは、この画面は、あらかじめ表示されるものではなく、呼び出されたときに別のウインドウで表示されるものであるために、ちょっと脇に置いて表示されているのです。






 次に、これらをつなぐ動作を記述するために、「入力ファイル選択」ボタンを押して、csファイルの編集画面を開きます。






上記完成画面を自分で表示し、プリントアウトして提出しなさい。


プログラムは、次を参照してください。




private void button1_Click(object sender, EventArgs e)
{
System.IO.StreamReader textFile;
string line;

// OpenfileDiag

DialogResult ret;

this.openFileDialog1.Title = "ファイル選択";
this.openFileDialog1.CheckFileExists = true;
this.openFileDialog1.RestoreDirectory = true;


ret = this.openFileDialog1.ShowDialog();

if (ret == DialogResult.OK)
{
this.label3.Text = this.openFileDialog1.FileName;
this.label5.Text = this.openFileDialog1.SafeFileName;
}
else
{
this.label3.Text = "No File";
this.label5.Text = "No File";

}
this.listBox1.Items.Clear();

textFile = new System.IO.StreamReader(
this.openFileDialog1.FileName, System.Text.Encoding.Default);
int num = 0;
while ((line = textFile.ReadLine()) != null)
{
this.listBox1.Items.Add(num.ToString() + ":\t" + line);
num++;
}
textFile.Close();

 【演習問題4】 

 Project604.cs ファイルをメールに添付して送りなさい。

 また、実行画面のコピーを提出しなさい。



 5.データファイルの読み込みとグラフ表示


 今までの作業結果を保存し、新しいプロジェクトを開始します。
 プロジェクト名   
Project605
 csファイル名   PictureFile1
としておきましょう。


 次のようなものを作ります。



 まず、データファイルを、

cdata  フォルダに、
data1.dat   という名前で作成しておきます。
 内容は、適当な数値でよいのですが、大体次のようなものにしてみます。(多少変えても構いません)

100
40
60
80
70
40
10
90
10
210
30
80
50
0


 プログラムは、次を参照してください。

  private void button1_Click(object sender, EventArgs e)
{
System.IO.StreamReader textFile;
string line;

int num;
int[] data_y ;
data_y = new int[100];

Graphics g = this.pictureBox1.CreateGraphics();
Pen redPen = new Pen(Color.Red, 2);

DialogResult ret;

this.openFileDialog1.Title = "ファイル選択";
this.openFileDialog1.CheckFileExists = true;
this.openFileDialog1.RestoreDirectory = true;
ret = this.openFileDialog1.ShowDialog();

if (ret == DialogResult.OK)
{
this.label2.Text = this.openFileDialog1.FileName;
this.label3.Text = this.openFileDialog1.SafeFileName;

}
else
{
this.label2.Text = "No File";
this.label3.Text = "No File";
this.pictureBox1.Image = null;
}

textFile = new System.IO.StreamReader(
this.openFileDialog1.FileName, System.Text.Encoding.Default);

num=0;

while ((line=textFile.ReadLine()) != null)
{
this.listBox1.Items.Add(num.ToString()+":\t"+line);

int.TryParse(line, out data_y[num]);

g.DrawEllipse(redPen, num * 10, data_y[num], 3, 3);
num++;
}
textFile.Close();



}


 【演習問題5】 

 Project605.cs ファイルをメールに添付して送りなさい。

 また、実行画面のコピーを提出しなさい。

 6.画像ファイルの表示
this.pictureBox1.Image = Image.FromFile()

今日は、ここまでできなくても良いです。先週のやり残しのある人はこの問題より前に先週のやり残し問題をやってください。
この課題は、来週もう一度やります。 
 ここで、ちょっと趣向を変えて、画像ファイルを表示するプログラムを作っておきましょう。

 今までの作業結果を保存し、新しいプロジェクトを開始します。
 プロジェクト名   
Project606
 csファイル名   ShowPicture1
としておきましょう。

 また、表示する画像ファイルとして、サンプル画像などのあるフォルダから、 cdata フォルダにコピーを作っておきます。

出来上がりイメージは次のようなものです。
(使用する画像は、別の物でも構いません。適当な画像がないときは、
先生の画像ファイルへのリンク
を使ってみてください。(学内専用))




PictureBox のプロパティ設定で、
下記のように、

SizeMode  を
StretchImage

 に設定しておくようにしてください。
 これを設定しないと、画像の一部しか表示されないことがあります。
 ただし、PictureBox を変形すると、画像もそれに合わせて変形されるので注意が必要です。
 余裕があったら、このモードをいろいろ変更して、試してみるとよいでしょう。

 この課題も、画像が表示された画面をプリントして提出してください。





  private void button1_Click(object sender, EventArgs e)
{


DialogResult ret;

this.openFileDialog1.Title = "ファイル選択";
this.openFileDialog1.CheckFileExists = true;
this.openFileDialog1.RestoreDirectory = true;
ret = this.openFileDialog1.ShowDialog();

if (ret == DialogResult.OK)
{
this.label3.Text = this.openFileDialog1.FileName;
this.label5.Text = this.openFileDialog1.SafeFileName;
this.pictureBox1.Image = Image.FromFile(this.openFileDialog1.FileName);

}
else
{
this.label3.Text = "No File";
this.label5.Text = "No File";
}
}

 【演習問題6】 

 Project606.cs ファイルをメールに添付して送りなさい。

 また、実行画面のコピーを提出しなさい。







 もし、一度作ったプロジェクトを再開するとき、
[デザイン]と名のついたウインドウが出てこないときには[.cs]ウインドウで、マウスを右クリックし、「デザイナの表示」を選びます。