2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【C#】メモ帳で開発(おまけ:ホスト計算ソフト)

Last updated at Posted at 2021-06-21

メモ帳を開発はしません、メモ帳で開発します。
自分用覚書その2。

自宅のノートPCがおんぼろなためか、VSC# を動かすとカクカクになってしまうので、やむなくCLI開発。
(※VisualStudio C# 使える人はそっち使った方が絶対に効率良い)

Windows には標準でC#のコンパイラやら何やらが入っているそうなので、それを使って開発していく。

C#のコンパイラのパスを通す

C#はコンパイル言語なのでコンパイラでコンパイルが必要。
割とパスの通し方忘れるのでメモ。

左下のWindows マークを右クリック。
設定 → システム → 詳細情報 → システムの詳細設定 で、システムのプロパティを開き、「環境変数(N)」を押下。

ユーザーの環境変数もしくは、システムの環境変数の「Path」を選択し、「編集」を押下。
環境変数の編集のウィンドウで「新規(N)」を押下すると、左のリストにあらたにパスを加えられる状態になるので、コンパイラが存在するフォルダを指定。

C:¥Windows¥Microsoft.NET¥Framework64¥v4.0.30319¥

パスがとっているか、以下のコマンドで確認。
このコンパイラは~~みたいな英文がでたら成功。

csc

コマンドプロンプトでソースコードを置くフォルダへ移動

なんかテキトーにフォルダ作ってそこに移動。
(例えばホームディレクトリに csharpProgramというフォルダ)

cd C:¥Users¥hemuwan¥csharpProgram

てきとーにプログラム書く。メモ帳起動はnotepad

notepad hello.cs

別に .txt でもいい。
お試しハローワールドサンプル。

hello.cs
using System;

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Hello World!");
  }
}

上記をコンパイルして実行すると、コンソールにHello Worldが表示される。

csharpProgram>csc hello.cs
csharpProgram>hello.exe
Hello World! 

それなりにいろいろできるよ

フォームを表示させるには、Main() の中で、Formクラスを継承したクラスのインスタンスを作成し、Application.Run()の引数に入れて使う。

sample.cs
using System.Windows.Forms;

class Program
{
  static void Main(string[] args)
  {
    Form1 form1 = new Form1();
    Application.Run(form1);
  }
}

class Form1 : Form
{
  
}

上記のコードをコンパイルし、.exe ファイルを実行すれば、フォームだけ表示される。

image.png

おめでとう、これでメモ帳とコマンドプロンプトを使った
C#の苦行開発環境が出来上がりだよ!

おまけ、IPアドレスから2進表記と割り当て可能ホスト数を計算してくれるプログラム

せっかくなんで作ってみた。
メーっちゃしんどいのでおとなしく統合開発環境を使うのが吉。

せっかくなので、試行錯誤のコメントもそのまま。
、、、んーしかし、汚い。

csharpIPConverter.cs
using System;
using System.Windows.Forms;
using System.Drawing;

//Formクラスを継承し、フォーム画面使えるように
class WinMain : Form
{
  public static void Main(string[] args)
  {
    WinMain win = new WinMain();
    win.Text = "IPアドレスを2進数に変換";

    //アプリケーション実行。これでフォームが立ち上がる。
    Application.Run(win);
  }//Main()


  //各部品のインスタンスを作る
  //最初コンストラクタ内で宣言しちゃったから?値の引き渡し失敗した。
  TextBox inputTxt = new TextBox();
  TextBox binTxt = new TextBox();
  TextBox hostCountTxt = new TextBox();
  Button btn1 = new Button();
  Label inputLbl = new Label();  //説明用
  Label binLbl = new Label();
  Label hostCountLbl = new Label();

  //コンストラクタ。フォームの部品などを定義
  //初期値を設定したり
  public WinMain()
  {
    //変数に入れるとき、this を付けた方が明示的か

    //各部品の情報を整える
    inputLbl.Text = "IPアドレスをCIDR表記で入力(例:192.168.1.0/24)";
    inputLbl.Bounds = new Rectangle(10, 10, 250, 20);

    inputTxt.Text = "IPアドレスを入力してください。";
    inputTxt.Bounds = new Rectangle(10, 30, 250, 20);

    btn1.Text = "実行";
    btn1.Bounds = new Rectangle(10, 60, 80, 25);

    binLbl.Text = "2進数に変換すると";
    binLbl.Bounds = new Rectangle(10, 110, 250, 20);

    binTxt.Bounds = new Rectangle(10, 130, 250, 20);

    hostCountLbl.Text = "割り当て可能なホスト数は";
    hostCountLbl.Bounds = new Rectangle(10, 160, 250, 20);

    hostCountTxt.Bounds = new Rectangle(10, 180, 250, 20);

    //ボタンを押して離したときに発動するメソッドを追加
    btn1.MouseUp += new MouseEventHandler(btn1_onclick);

    //部品をフォームに表示
    Controls.Add(inputLbl);
    Controls.Add(inputTxt);
    Controls.Add(btn1);
    Controls.Add(binLbl);
    Controls.Add(binTxt);
    Controls.Add(hostCountLbl);
    Controls.Add(hostCountTxt);    
  }//WinMain() コンストラクタ

  //btn1を押したときのメソッドを定義、名前に決まりはないみたいだけど
  //合わせておいた方がわかり易い。
  public void btn1_onclick(object sender, MouseEventArgs e)
  {
    //入力テキストを受け取り、アドレス計算
    IPaddrConverter(inputTxt.Text);
  }

  void IPaddrConverter(string IPaddress)
  {   
    //変数名、雑すぎてやばい
    string IPaddr = IPaddress;
    string[] ip = IPaddr.Split('/');
    string prefix = ip[1];  //別に代入せんでよかったのでは。

    string[] oxet = ip[0].Split('.');
    for(int i = 0; i < oxet.Length; i++)
      Console.WriteLine(oxet[i]);// 192  168  1  0

    string[] convertOxet = new string[4];

    //2進数に変換した後、
    //00000000.00000000.00000000.00000000の表記にするため、頭に0付けていく
    for(int i = 0; i < oxet.Length; i++)
    {
      convertOxet[i] = Convert.ToString(Convert.ToInt32(oxet[i]), 2);
      if(convertOxet[i].Length < 8)
      {
        //loopCounter にループ回数を代入。
        //最初これをそのままfor文に入れて、値が変わってうまくいかんかった。
        int loopCounter = 8 - convertOxet[i].Length;
        for(int j = 0; j < loopCounter; j++)
        {
          //Console.WriteLine(8 - convertOxet[i].Length);
          convertOxet[i] = "0" + convertOxet[i];
        }
      }           
      Console.WriteLine(convertOxet[i]);
    }

    //192.168.1.0 を 2進数表記 00000000.00000000.00000000.00000000で表示
    //192.168.1.0 -> 11000000.10101000.00000001.00000000
    //Console.WriteLine("{0}", string.Join(".", convertOxet));
    binTxt.Text = string.Join(".", convertOxet);

    //プレフィックス prefix を使って、割り当て可能ホスト数を割り出す。
    //ビットを2進数に直して、それをまた10進に直して、2引くでいこう
    //32 - 24 = 8 -> 8bit = 256 -2 => 割り当て可能ホスト数 254 個 になるはず
    //うまくいかず。。32 - prefix はビットの数なので2進数に変換しても変になる
    //32 - prefix の数ぶん、1 を立てる
    int bitCounter = 32 - int.Parse(prefix);// 32 - 24 = 8
    string hostBit = "";
    for(int i = 0; i < bitCounter; i++)
    {
      hostBit = "1" + hostBit;
    }

    long hostCounter = Convert.ToInt64(hostBit, 2) - 1;
    hostCountTxt.Text = Convert.ToString(hostCounter);
  }
}//class WinMain : Form

image.png

xxx.xxx.xxx.xxx/xx の表記で入力してね。
違うとバグるよ。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?