ひらがな・カタカナを連番と同じように表示していくプログラム[c#][powershell]

2021-10-02

皆さん、資料に項番をつける作業はお好きですか?私は嫌いです。
だって必ず途中で文章とか増やしてしまって項番が合わなくなるんですもん…。

連番なら簡単です。ExcelでもWordでもなんだかんだうまく採番してくれるので。けど文字とか順番に表示してもらおうと思うといちいち手で書くしかなくて私は苦痛しか感じません。

というわけでツールを作ろうとしたんですが。

string[] kouban = {"ア","イ","ウ","エ" };

こうやって全部カタカナを順番にコード内にに書くのが手間すぎて。
自分用のツールなので必要な連番が増えるたびにコードをちまちま修正していたんですけど、嫌になったのでカタカナの連番処理の部分もコードでなんとかしようと今回思い立ちました。配列に全部書くよりコード書く時間の方がかかるとか言ってはいけない。

この記事ではこうやって全部カタカナとかひらがなをコード上で羅列しなくても順番に表示できる方法を書いていきます!

まずは基本の連番から

連番は簡単です。だってループするだけだもの。

using System;

namespace ConsoleApp13
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++) {
                Console.Write(i);
            }
            Console.ReadLine();
        }
    }
}

これくらいなら皆さん問題なくできるはず。

結果もこの通り。

アルファベットを順番に表示する

アルファベットを順番に表示するのは少しだけ文字コードの知識が必要になります。

Windowsのパソコンを使用している方なら、IMEパッドを表示すると分かりやすいと思うんですけど、文字にはパソコンが認識するための番号が振られています。そして、その番号を使って文字を逆引きすることもプログラミングなら可能です

アルファベットは図のように大文字なら41~5A(※16進数表記)というように連続で振られています。

using System;
using System.Text;

namespace ConsoleApp13
{
    class Program
    {
        static void Main()
        {
            char[] a = { 'A' };
            byte[] byteA = Encoding.ASCII.GetBytes(a);

            for (int i = 0; i < 26; i++) {
                string alphabet = Encoding.ASCII.GetString(byteA);
                Console.Write(alphabet);
                byteA[0] += 1;
            }
            Console.ReadLine();
        }
    }
}

ざっと書くとこんな感じ。こちらは文字「A」を一回バイトコード(パソコンの内部値)に変えてから内部値に+1ずつ足して表示…ということを繰り返しています。

たしかCであればもっと簡単なコードで羅列できます。興味があったら調べてみてください。

実行するとこんな結果が得られます。

char[] a = { 'a' };

10行目を置き換えるだけで小文字のアルファベットも羅列可能です。

カタカナ・ひらがなを順番に表示する

ここで本題のひらがな・カタカナの羅列!先ほどのアルファベットと同じようにfor文だけで完結させたいのですが、少し問題が。

先ほどのアルファベットと違って、綺麗に順番に並んでいません。これだとfor文でぐるぐる回しても濁音文字とかが間に混ざってきてしまいます。

さて、どうするか

日本語ってカタカナ・ひらがな・漢字以外にも使えるものがあります。それが「半角カナ」!!

半角カナだけは何故か私たちが思うような順番に近い形で登録されているんです。
つまり「半角カナで連番→カタカナなりひらがなに変換」すれば上手く取得可能です。

とはいえ「ヲ」だけは何故か先頭にあるので使用したいならあとで調整する必要性があるのですが。わたしは面倒なのでこちらは無視することにします。

using System;
using System.Text;

namespace ConsoleApp13
{
    class Program
    {
        static void Main()
        {
            char[] a = { 'ア' };
            byte[] byteA = Encoding.GetEncoding("shift_jis").GetBytes(a);

            for (int i = 0; i < 45; i++) {
                string hanKana = Encoding.GetEncoding("shift_jis").GetString(byteA);
                string kana = Microsoft.VisualBasic.Strings.StrConv(hanKana, Microsoft.VisualBasic.VbStrConv.Wide, 0x411);
                Console.Write(kana);
                byteA[0] += 1;
            }
            Console.ReadLine();
        }
    }
}

で、実装したのがこちらのコードになります。

実行結果はこんな感じ。見事に順番になっています。

アルファベットを順番に表示していた時の違いは

  • 文字コード(ASCII→sjis)
    ASCIIは日本語対応していない文字コードのため。UTF-8でもBOMなしなら同じ要領で可能です。
  • 参照に”Microsoft.VisualBasic”を追加
    半角カナ→全角カナの処理をするため。これに準ずるライブラリいれるのもアリ。

の2点になります。

さらにさらに、ひらがな出力ならこのようなコードになります。

using System;
using System.Text;

namespace ConsoleApp13
{
    class Program
    {
        static void Main()
        {
            char[] a = { 'ア' };
            byte[] byteA = Encoding.GetEncoding("shift_jis").GetBytes(a);

            for (int i = 0; i < 45; i++) {
                string hanKana = Encoding.GetEncoding("shift_jis").GetString(byteA);
                string katakana = Microsoft.VisualBasic.Strings.StrConv(hanKana, Microsoft.VisualBasic.VbStrConv.Wide, 0x411);
                string hiragana = Microsoft.VisualBasic.Strings.StrConv(katakana, Microsoft.VisualBasic.VbStrConv.Hiragana, 0x411);
                Console.Write(hiragana);
                byteA[0] += 1;
            }
            Console.ReadLine();
        }
    }
}

先ほどのカタカナ出力からさらにひらがなに変換して出力しています。

この方法はVisualBasic用のライブラリを使用して変換しているのでC#じゃなくてもWindows環境上でさえあればわりと動かしやすいんじゃないでしょうか。

おまけ

ひらがな連続コードのpowershell版も一緒に載せておきます。

[reflection.assembly]::LoadWithPartialName("Microsoft.VisualBasic") > $Null

$a = @('ア')
$byteA = [System.Text.Encoding]::GetEncoding("shift_jis").GetBytes($a);
for($i = 0;$i -lt 45;$i++){
    $hankana = [System.Text.Encoding]::GetEncoding("shift_jis").GetString($byteA)
    $katakana = [Microsoft.VisualBasic.Strings]::StrConv($hankana, [Microsoft.VisualBasic.VbStrConv]::Wide,0x411)
    $hiragana = [Microsoft.VisualBasic.Strings]::StrConv($katakana, [Microsoft.VisualBasic.VbStrConv]::Hiragana,0x411)
    Write-Output $hiragana
    $byteA[0]+=1
}

powershellの場合、C#とある程度までは互換性があるので形式は変わるもののほぼ同じコードで何とかなります。