C# で固定長ファイルをライブラリで扱おうとして、全角が2バイトにカウントされないのでライブラリの使用は諦めました。
仕方がないので地道にファイルを読み込んで処理しようと思ったのですが、なんと 全角を2バイトカウントするにはエンコードを sjis にしないといけないそうな。
とりあえず下のようなコードを書いてみました。
拡張メソッドを使ってみました。
拡張メソッドを使うとあたかも string オブジェクトにメソッドが追加されたように書くことができるのでこの方がすっきりします。
Substring がバイトに対応したと言うことで SubstringB です。VB の MidB 的な感じで。
using System.Diagnostics;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string str = "abcdあいう";
Debug.WriteLine("通常:" + str.Substring(4, 2));
Debug.WriteLine("固定長(普通のメソッド):" + SubstringB0(str, 4, 2));
Debug.WriteLine("固定長(拡張メソッド):" + str.SubstringB(4, 2));
}
public static string SubstringB0(string str, int startIndex, int length)
{
Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
int c = 0;
string s = string.Empty;
for (int i = 0; i < str.Length; i++)
{
if (startIndex <= c && c < (startIndex + length - 1))
{
s += str.Substring(i, 1);
}
Debug.WriteLine(str.Substring(i, 1) + " " + i + " " + c);
c += sjisEnc.GetByteCount(str.Substring(i, 1));
}
return s;
}
}
static class StringExtensions
{
public static string SubstringB(this string str, int startIndex, int length)
{
Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
int c = 0;
string s = string.Empty;
for (int i = 0; i < str.Length; i++)
{
if (startIndex <= c && c < (startIndex + length - 1))
{
s += str.Substring(i, 1);
}
Debug.WriteLine(str.Substring(i, 1) + " " + i + " " + c);
c += sjisEnc.GetByteCount(str.Substring(i, 1));
}
return s;
}
}
}