学内ハッカソンに自作C言語エディタ出してみた

# はじめに
我が校で学内ハッカソンが行われました。
発表した作品の説明とハッカソンの感想を書きます。

# 開発環境
OS:Windows11
エディタ:Visual Studio 2022
言語:C#
フレームワーク:.NET Framework 4.7.2

# 作ったもの
タイトルにも書いたとおり、C言語専用の自作エディタです。
このソフトはC言語の基本的な文法しかサポートしておらず、色分けもされないので実用性は<font color="red">皆無</font>です。
唯一ほかのエディタに勝てる点は容量の軽さですね。34KBです。
高専1年生の宿題とかに使えたらいいなと思い作成しました。
レイアウトはこんな感じです。
![スクリーンショット 2023-03-08 001407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052827/8d413af1-282d-bfa5-a7f6-9e932915f5b3.png)
コンパイル・実行はボタンを押すだけで一発で行えるようになっています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052827/437b44e8-24aa-a30c-cedc-4a09d88be657.png" width="200">

↑これはソフトのアイコンで、ペアの友達にデザインしてもらいました。<b>
かっこいいです。

# システム構成
C#で書いています。
コンパイラはGCCを使わせていただきました。自作じゃないです。<b>GCC神！</b>

```c#
 var compile = new ProcessStartInfo()
 {
    fileName = "gcc.exe",
    WorkingDirectory=dic,
    CreateNoWindow=true,
    Arguments = $"{name+ "_temp.c"} -finput-charset=utf-8 -fexec-charset=cp932 -o {name + ".exe"}",
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true
 };
 var process = Process.Start(compile);
 process.WaitForExit();
```
コンパイルするためのプログラムです。
この部分が1番難しかったです。
C#からGCCコンパイラを使う方法は[こちら](https://qiita.com/sigh_kgr/items/542571e9d45e99392ada)の記事を参考にさせていただきました。
### 文字化け
もともと「gcc -o filename.exe ./filename.c」
という普通のコンパイルのコマンドを使用するはずでしたが、コンソールと実行ファイルの文字コードの違いにより文字化けが起きました。
解決策として、コンパイルのコマンドに
「-finput-charset=utf-8 -fexec-charset=cp932」を設けました。
これにより作成されるexeファイルの中の文字コードはコンソールに合わせたutf8になり、日本語の文字化けが起きなくなります。

### コンソールが閉じてしまう
さて、コンパイルまではうまくいったのですがここである問題が生じます。
コンソールでCのexeファイルを実行したときプログラムの終了とともにウインドウも一緒に閉じてしまうというものです。

解決策としてコンパイル時に1度Cのファイルを書き換えてプログラムを終了させないようにしています。
main関数の最後に「while(1){}」を置くという荒業です。

<details><summary><font color="red">くそコード注意</font></summary>

```c#
string txt="";
            using (StreamReader sr = new StreamReader(fileName, Encoding.UTF8))
            {
                txt = sr.ReadToEnd();
            }

            int len = txt.Length;
            int main_void;
            int main;
            if (txt.LastIndexOf(" main(void)") == -1)
            {
                main_void = len+100;
            }
            else
            {
                main_void = txt.LastIndexOf(" main(void)");
            }
            
            if(txt.LastIndexOf(" main()") == -1)
            {
                main = len+100;
            }
            else
            {
                main = txt.LastIndexOf(" main()");
            }

            if (txt.IndexOf("return",0) != -1)
            {
                if ((main_void < txt.LastIndexOf("return")) || (main < txt.LastIndexOf("return")))
                {
                    txt = txt.Insert(txt.LastIndexOf("return"), "while(1){}");
                }
                else {
                    txt = txt.Insert(txt.LastIndexOf("}"), "while(1){}");
                }
            }

            if (txt.IndexOf("return", 0) == -1)
            {
                txt = txt.Insert(txt.LastIndexOf("}") - 1, "while(1){}");
            }

            StreamWriter c = File.CreateText(dic+"\\"+name+"_temp.c");
            c.WriteLine(txt);
            c.Close();
```

</details>


このソフトでのコンパイルは下のように行われています。

コンパイルボタンが押される
↓
保存したCファイルのコピーを作る
↓
コピーを書き換え
↓
コピーをコンパイルする
↓
コピーのCファイルを削除

この一連の動作によりあたかも自分の書いたCファイルがコンソールで動いているように見えます。

# ハッカソンの感想
楽しかった。
周りはアイデアに振っている作品が多くて刺激を受けることができた。
自分の作品は学生より企業さんのほうがうけが良かったように感じた。
最終的に企業賞を貰えたので自己肯定感がup↑↑した。
いい経験になりました。

# 参考サイト
https://qiita.com/sigh_kgr/items/542571e9d45e99392ada