C#でstringの桁数を取得する方法|Lengthで文字数・全角半角・バイト数の違いまで解説
はじめに
C#でstringの桁数を取得したい場合、もっとも基本的にはLengthプロパティを使います。
ただし、ひとことで「桁数」といっても、実際には次のように意味が分かれます。
文字数を数えたい
全角を2桁、半角を1桁として数えたい
バイト数を数えたい
入力フォームやDB登録時の制限に使いたい
指定桁数で文字列を切り出したい
C#のstring.Lengthで取得できるのは、基本的に「文字列に含まれるcharの数」です。そのため、全角文字を2文字として数えたり、UTF-8やShift_JISのバイト数を取得したりしたい場合は、別の方法で実装する必要があります。
この記事では、C#でstringの桁数を取得する基本から、Lengthの注意点、全角・半角を考慮した桁数の数え方、バイト数チェック、文字列の切り出し方法まで解説します。
1. C#でstringの桁数を取得する基本
1-1. stringの「桁数」はLengthで取得できる
C#で文字列の桁数、つまり文字数を取得するには、string.Lengthを使います。
C#string text = "Hello";
int length = text.Length;
Console.WriteLine(length);
実行結果は次のとおりです。
5
Lengthは、文字列に含まれる文字数をint型で返します。
C#string name = "山田太郎";
Console.WriteLine(name.Length);
実行結果は次のようになります。
4
日本語のような全角文字であっても、Lengthでは1文字を1として数えます。
1-2. Lengthの基本構文とサンプルコード
Lengthはメソッドではなくプロパティです。そのため、Length()のように丸括弧を付ける必要はありません。
C#文字列.Length
基本的な使い方は次のとおりです。
C#string str = "C#入門";
int count = str.Length;
Console.WriteLine($"文字数は{count}です。");
実行結果は次のようになります。
文字数は4です。
C、#、入、門の4文字として数えられます。
入力チェックでもよく使われます。
C#string userName = "Tanaka";
if (userName.Length <= 10)
{
Console.WriteLine("10文字以内です。");
}
else
{
Console.WriteLine("10文字を超えています。");
}
このように、C#でstringの文字数を確認する場合は、まずLengthを使うのが基本です。
1-3. 空文字・nullの場合の扱い
空文字の場合、Lengthは0を返します。
C#string empty = "";
Console.WriteLine(empty.Length);
実行結果は次のとおりです。
0
一方、nullの文字列に対してLengthを使うと、NullReferenceExceptionが発生します。
C#string text = null;
Console.WriteLine(text.Length);
このコードは実行時エラーになります。
nullの可能性がある場合は、事前にチェックしましょう。
C#string text = null;
int length = text == null ? 0 : text.Length;
Console.WriteLine(length);
または、null条件演算子を使って次のように書けます。
C#string text = null;
int length = text?.Length ?? 0;
Console.WriteLine(length);
text?.Lengthは、textがnullの場合にnullを返します。そこに?? 0を付けることで、nullの場合は0として扱えます。
空文字とnullは別物です。
C#string empty = "";
string nullText = null;
Console.WriteLine(empty.Length); // 0
Console.WriteLine(nullText?.Length ?? 0); // 0
どちらも桁数としては0扱いにすることが多いですが、意味としては異なるため、入力チェックでは注意しましょう。
1-4. Count()ではなくLengthを使うべき理由
文字列の文字数は、LINQのCount()でも取得できます。
C#using System.Linq;
string text = "Hello";
int count = text.Count();
Console.WriteLine(count);
実行結果は5です。
しかし、文字列の長さを取得するだけであれば、基本的にはCount()ではなくLengthを使うべきです。
C#int length = text.Length;
理由は、Lengthの方がシンプルで高速だからです。
Lengthは文字列が持っている長さ情報を取得するだけです。一方、Count()は文字列を列挙して数える処理になるため、文字数取得だけが目的なら不要な処理が増えます。
比較すると次のようになります。
| 方法 | 用途 | 推奨度 |
|---|---|---|
text.Length | 文字列の文字数を取得する | 高い |
text.Count() | 条件付きで要素数を数える場合など | 通常は不要 |
たとえば、単純に文字列の桁数を知りたいだけなら、次のように書きます。
C#string text = "C# string";
Console.WriteLine(text.Length);
Count()を使うのは、条件に一致する文字だけを数えるようなケースです。
C#using System.Linq;
string text = "A1B2C3";
int digitCount = text.Count(char.IsDigit);
Console.WriteLine(digitCount);
実行結果は次のとおりです。
3
このように、文字列全体の桁数を取得するならLength、特定条件の文字数を数えるならCount()と使い分けるとよいでしょう。
2. C#のstring.Lengthで取得できるのは「文字数」
2-1. Lengthは文字列内のChar数を返す
C#のstring.Lengthは、文字列に含まれるcharの数を返します。
C#string text = "ABC";
Console.WriteLine(text.Length);
実行結果は次のとおりです。
3
ここで重要なのは、Lengthが返すのは「画面上の見た目の文字数」や「バイト数」ではなく、C#の文字列内部に含まれるcharの数だという点です。
C#のcharはUTF-16のコード単位を表します。そのため、多くの日本語や英数字は1文字につきLengthが1増えますが、絵文字など一部の文字では、見た目の1文字とLengthの値が一致しない場合があります。
まずは、通常の日本語や英数字ではLengthが文字数として使える、と理解しておけば問題ありません。
2-2. 全角文字も半角文字もLengthでは1文字として数える
Lengthでは、全角文字も半角文字も1文字として数えます。
C#string half = "ABC";
string full = "ABC";
Console.WriteLine(half.Length);
Console.WriteLine(full.Length);
実行結果は次のとおりです。
3
3
半角のABCも、全角のABCも、どちらも3文字として扱われます。
日本語も同じです。
C#string text = "あいうえお";
Console.WriteLine(text.Length);
実行結果は次のとおりです。
5
Lengthは「全角だから2」「半角だから1」という数え方はしません。
そのため、次のような桁数チェックにはそのまま使えます。
C#string input = "東京都";
if (input.Length <= 10)
{
Console.WriteLine("10文字以内です。");
}
一方で、帳票や古いシステム連携などで「全角は2桁、半角は1桁」として扱いたい場合は、Lengthだけでは不十分です。
2-3. 日本語・英数字・記号が混在する文字列のカウント例
日本語、英数字、記号が混在する文字列でも、Lengthは基本的に1文字ずつ数えます。
C#string text = "C#入門123";
Console.WriteLine(text.Length);
この文字列は次の8文字です。
C
#
入
門
1
2
3
実行結果は次のようになります。
7
もう少し複雑な例を見てみましょう。
C#string text = "商品A-100円";
Console.WriteLine(text.Length);
文字ごとに分けると次のようになります。
| 文字 | カウント |
|---|---|
| 商 | 1 |
| 品 | 1 |
| A | 1 |
| - | 1 |
| 1 | 1 |
| 0 | 1 |
| 0 | 1 |
| 円 | 1 |
合計は8です。
8
全角・半角が混在していても、Lengthでは基本的に「1文字は1」として数えられます。
C#string text = "ABCあいう";
Console.WriteLine(text.Length);
実行結果は次のとおりです。
6
半角英字3文字、日本語3文字なので、合計6文字です。
2-4. 絵文字やサロゲートペアでLengthが想定とずれるケース
Lengthを使うときに注意したいのが、絵文字や一部の特殊文字です。
たとえば、次のコードを見てください。
C#string text = "😀";
Console.WriteLine(text.Length);
見た目は絵文字1文字ですが、実行結果は次のようになる場合があります。
2
これは、絵文字がUTF-16では2つのchar、つまりサロゲートペアとして表現されることがあるためです。
次のように、通常の文字と絵文字を混ぜると分かりやすいです。
C#string text = "A😀B";
Console.WriteLine(text.Length);
見た目はA、😀、Bの3文字ですが、Lengthは次のようになります。
4
Aが1、絵文字が2、Bが1として数えられるためです。
また、絵文字には複数のコードポイントを組み合わせて1つの見た目にしているものもあります。そのため、「ユーザーが見た目で認識する文字数」を正確に数えたい場合は、Lengthだけでは足りません。
見た目上の文字単位で数えたい場合は、StringInfoを使う方法があります。
C#using System.Globalization;
string text = "A😀B";
int count = new StringInfo(text).LengthInTextElements;
Console.WriteLine(count);
LengthはC#の文字列処理では便利ですが、絵文字や合成文字を含む場合は「見た目の文字数」と一致しないことを覚えておきましょう。
3. 全角・半角を考慮した桁数の数え方
3-1. 「全角2桁・半角1桁」として数えたいケース
C#でstringの桁数を扱うとき、業務システムでは「全角2桁、半角1桁」として数えたいケースがあります。
たとえば、次のような場面です。
帳票の表示幅を合わせたい
固定長ファイルを作成したい
古い基幹システムと連携したい
入力フォームで「全角10文字または半角20文字まで」のように制限したい
Shift_JIS前提のバイト数制限を行いたい
Lengthでは、全角も半角も1として数えられます。
C#string text = "ABCあいう";
Console.WriteLine(text.Length);
実行結果は次のとおりです。
6
しかし、「半角1桁、全角2桁」として数えるなら、次のように考えます。
| 文字 | 桁数 |
|---|---|
| A | 1 |
| B | 1 |
| C | 1 |
| あ | 2 |
| い | 2 |
| う | 2 |
合計は9桁です。
このような数え方をしたい場合は、Lengthではなく、文字ごとに判定する方法や、Shift_JISなどのエンコーディングを使ってバイト数から求める方法があります。
3-2. Encodingを使ってバイト数から桁数を取得する方法
全角を2桁、半角を1桁として数えたい場合、よく使われるのがEncoding.GetByteCountです。
たとえば、Shift_JISでは多くの半角英数字は1バイト、日本語などの全角文字は2バイトとして扱われます。そのため、Shift_JISのバイト数を取得すると、「全角2桁・半角1桁」に近い値を取得できます。
C#using System.Text;
string text = "ABCあいう";
Encoding sjis = Encoding.GetEncoding("shift_jis");
int byteCount = sjis.GetByteCount(text);
Console.WriteLine(byteCount);
実行結果は次のようになります。
9
ABCが3バイト、あいうが6バイトなので、合計9バイトです。
この値を「桁数」として使えば、全角2桁・半角1桁のチェックができます。
ただし、.NET Coreや.NET 5以降でShift_JISを使う場合は、コードページプロバイダーの登録が必要になることがあります。
C#using System.Text;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
プロジェクトによっては、System.Text.Encoding.CodePagesパッケージの追加が必要です。
3-3. Shift_JISで全角2バイト・半角1バイトとして数える例
Shift_JISでバイト数を取得し、全角2桁・半角1桁として扱う例を見てみましょう。
C#using System;
using System.Text;
class Program
{
static void Main()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string text = "ABCあいう";
Encoding sjis = Encoding.GetEncoding("shift_jis");
int digitCount = sjis.GetByteCount(text);
Console.WriteLine($"桁数: {digitCount}");
}
}
実行結果は次のとおりです。
桁数: 9
入力値が指定桁数以内かチェックする場合は、次のように書けます。
C#using System.Text;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string input = "ABCあいう";
int maxLength = 10;
Encoding sjis = Encoding.GetEncoding("shift_jis");
int digitCount = sjis.GetByteCount(input);
if (digitCount <= maxLength)
{
Console.WriteLine("指定桁数以内です。");
}
else
{
Console.WriteLine("指定桁数を超えています。");
}
共通メソッドにすると便利です。
C#using System.Text;
public static bool IsWithinSjisLength(string? text, int maxLength)
{
if (text == null)
{
return true;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
return sjis.GetByteCount(text) <= maxLength;
}
使用例は次のとおりです。
C#Console.WriteLine(IsWithinSjisLength("ABC", 5)); // True
Console.WriteLine(IsWithinSjisLength("あいう", 5)); // False
Console.WriteLine(IsWithinSjisLength("あい", 5)); // True
あいうはShift_JISで6バイトになるため、最大5桁を超えます。
3-4. UTF-8では全角が必ず2バイトにならない点に注意
バイト数を使って桁数を取得するときは、どのエンコーディングを使うかが非常に重要です。
特に注意したいのがUTF-8です。
UTF-8では、半角英数字は1バイトですが、日本語は多くの場合3バイトになります。
C#using System.Text;
string text = "ABCあいう";
int byteCount = Encoding.UTF8.GetByteCount(text);
Console.WriteLine(byteCount);
実行結果は次のようになります。
12
内訳は次のとおりです。
| 文字 | UTF-8のバイト数 |
|---|---|
| A | 1 |
| B | 1 |
| C | 1 |
| あ | 3 |
| い | 3 |
| う | 3 |
合計は12バイトです。
つまり、UTF-8のバイト数は「全角2桁・半角1桁」とは一致しません。
全角を2桁、半角を1桁として数えたいなら、UTF-8ではなくShift_JISのバイト数を使うか、文字ごとに幅を判定する実装が必要です。
ただし、現代のWebアプリケーションやAPIではUTF-8が使われることが多いため、DBや外部システムがどの文字コードを前提としているかを確認してから実装することが重要です。
4. stringのバイト数を取得する方法
4-1. Encoding.GetByteCountでバイト数を取得する
C#でstringのバイト数を取得するには、Encoding.GetByteCountを使います。
C#Encoding.エンコーディング.GetByteCount(文字列)
代表的なエンコーディングには次のようなものがあります。
| エンコーディング | 説明 |
|---|---|
Encoding.UTF8 | UTF-8でのバイト数を取得する |
Encoding.Unicode | UTF-16リトルエンディアンでのバイト数を取得する |
Encoding.GetEncoding("shift_jis") | Shift_JISでのバイト数を取得する |
文字数とバイト数は異なります。
C#using System.Text;
string text = "ABCあいう";
Console.WriteLine(text.Length);
Console.WriteLine(Encoding.UTF8.GetByteCount(text));
実行結果は次のようになります。
6
12
Lengthは文字数、GetByteCountは指定した文字コードでエンコードした場合のバイト数です。
4-2. UTF-8のバイト数を取得するコード例
UTF-8でのバイト数を取得するには、Encoding.UTF8.GetByteCountを使います。
C#using System;
using System.Text;
class Program
{
static void Main()
{
string text = "ABCあいう";
int byteCount = Encoding.UTF8.GetByteCount(text);
Console.WriteLine($"UTF-8のバイト数: {byteCount}");
}
}
実行結果は次のとおりです。
UTF-8のバイト数: 12
UTF-8では、半角英数字は1バイト、日本語は多くの場合3バイトになります。
絵文字を含む場合は、さらにバイト数が増えることがあります。
C#using System.Text;
string text = "A😀B";
int byteCount = Encoding.UTF8.GetByteCount(text);
Console.WriteLine(byteCount);
この場合、AとBはそれぞれ1バイト、絵文字は4バイトとして扱われるため、結果は次のようになります。
6
UTF-8のバイト数は、Web API、JSON、ファイル出力、DBのバイト制限などを確認するときに使われます。
4-3. Shift_JISのバイト数を取得するコード例
Shift_JISでのバイト数を取得するには、Encoding.GetEncoding("shift_jis")を使います。
C#using System;
using System.Text;
class Program
{
static void Main()
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string text = "ABCあいう";
Encoding sjis = Encoding.GetEncoding("shift_jis");
int byteCount = sjis.GetByteCount(text);
Console.WriteLine($"Shift_JISのバイト数: {byteCount}");
}
}
実行結果は次のとおりです。
Shift_JISのバイト数: 9
Shift_JISでは、半角英数字が1バイト、日本語の多くが2バイトとして扱われます。
そのため、次のような入力チェックで使えます。
C#using System.Text;
public static bool IsWithinShiftJisBytes(string? text, int maxBytes)
{
if (string.IsNullOrEmpty(text))
{
return true;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
return sjis.GetByteCount(text) <= maxBytes;
}
使用例は次のとおりです。
C#Console.WriteLine(IsWithinShiftJisBytes("ABC", 5)); // True
Console.WriteLine(IsWithinShiftJisBytes("あいう", 5)); // False
Console.WriteLine(IsWithinShiftJisBytes("AあB", 5)); // True
AあBは、Aが1バイト、あが2バイト、Bが1バイトなので、合計4バイトです。
4-4. 文字数とバイト数の違いを比較表で整理
Lengthで取得する文字数と、Encoding.GetByteCountで取得するバイト数は異なります。
次の文字列で比較してみます。
C#string text = "ABCあいう";
| 取得方法 | 結果 | 意味 |
|---|---|---|
text.Length | 6 | C#のchar数 |
Encoding.UTF8.GetByteCount(text) | 12 | UTF-8でエンコードした場合のバイト数 |
Encoding.GetEncoding("shift_jis").GetByteCount(text) | 9 | Shift_JISでエンコードした場合のバイト数 |
それぞれの違いは次のとおりです。
| 観点 | 文字数 | バイト数 |
|---|---|---|
| 取得方法 | Length | Encoding.GetByteCount |
| 文字コードの影響 | 基本的に受けない | 受ける |
| 全角・半角の扱い | どちらも基本1文字 | 文字コードにより異なる |
| 主な用途 | 入力文字数チェック | DB、ファイル、通信、外部連携のサイズチェック |
実装時は、「何を制限したいのか」を明確にしてから使い分けることが大切です。
たとえば、ユーザーに「20文字以内で入力してください」と表示するならLengthが向いています。
一方で、「Shift_JISで20バイト以内にしてください」という外部システム連携の制約があるなら、Shift_JISのGetByteCountを使うべきです。
5. 桁数チェック・入力制限でよく使う実装例
5-1. 指定した文字数以内かチェックする
指定した文字数以内かチェックする場合は、Lengthを使います。
C#public static bool IsWithinLength(string? text, int maxLength)
{
if (text == null)
{
return true;
}
return text.Length <= maxLength;
}
使用例は次のとおりです。
C#Console.WriteLine(IsWithinLength("Hello", 10)); // True
Console.WriteLine(IsWithinLength("こんにちは", 3)); // False
Console.WriteLine(IsWithinLength(null, 10)); // True
空文字やnullを許可しない場合は、別途チェックします。
C#public static bool IsRequiredAndWithinLength(string? text, int maxLength)
{
if (string.IsNullOrWhiteSpace(text))
{
return false;
}
return text.Length <= maxLength;
}
このメソッドでは、null、空文字、空白だけの文字列を不正として扱います。
C#Console.WriteLine(IsRequiredAndWithinLength("", 10)); // False
Console.WriteLine(IsRequiredAndWithinLength(" ", 10)); // False
Console.WriteLine(IsRequiredAndWithinLength("Tokyo", 10)); // True
5-2. 全角半角を考慮して指定桁数以内かチェックする
全角を2桁、半角を1桁として指定桁数以内かチェックしたい場合は、Shift_JISのバイト数を使う方法があります。
C#using System.Text;
public static bool IsWithinZenkakuHankakuLength(string? text, int maxLength)
{
if (string.IsNullOrEmpty(text))
{
return true;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
int length = sjis.GetByteCount(text);
return length <= maxLength;
}
使用例は次のとおりです。
C#Console.WriteLine(IsWithinZenkakuHankakuLength("ABC", 5)); // True
Console.WriteLine(IsWithinZenkakuHankakuLength("あい", 5)); // True
Console.WriteLine(IsWithinZenkakuHankakuLength("あいう", 5)); // False
Console.WriteLine(IsWithinZenkakuHankakuLength("AあB", 5)); // True
あいうは全角3文字なので、全角2桁換算では6桁です。そのため、最大5桁を超えます。
ただし、Shift_JISで表現できない文字が含まれる場合は、代替文字として扱われることがあります。絵文字や一部の特殊文字を含む可能性がある場合は、要件に合わせたチェックが必要です。
5-3. バイト数制限以内かチェックする
バイト数制限以内かチェックする場合は、使用する文字コードを引数で受け取る形にすると汎用的です。
C#using System.Text;
public static bool IsWithinByteCount(string? text, int maxBytes, Encoding encoding)
{
if (string.IsNullOrEmpty(text))
{
return true;
}
int byteCount = encoding.GetByteCount(text);
return byteCount <= maxBytes;
}
UTF-8でチェックする場合は次のように使います。
C#string input = "ABCあいう";
bool result = IsWithinByteCount(input, 12, Encoding.UTF8);
Console.WriteLine(result); // True
Shift_JISでチェックする場合は次のように使います。
C#using System.Text;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string input = "ABCあいう";
Encoding sjis = Encoding.GetEncoding("shift_jis");
bool result = IsWithinByteCount(input, 8, sjis);
Console.WriteLine(result); // False
バイト数制限は、DBのカラム制限やファイルフォーマット、外部APIの仕様に合わせて使います。
たとえば、UTF-8で最大10バイト以内に制限する場合は次のようになります。
C#string input = "あいう";
if (Encoding.UTF8.GetByteCount(input) <= 10)
{
Console.WriteLine("10バイト以内です。");
}
else
{
Console.WriteLine("10バイトを超えています。");
}
あいうはUTF-8で9バイトなので、10バイト以内です。
5-4. 桁数オーバー時にエラーメッセージを返す
入力チェックでは、trueまたはfalseだけでなく、エラーメッセージを返したいこともあります。
文字数チェックの例です。
C#public static string? ValidateLength(string? text, int maxLength, string fieldName)
{
if (string.IsNullOrEmpty(text))
{
return null;
}
if (text.Length > maxLength)
{
return $"{fieldName}は{maxLength}文字以内で入力してください。";
}
return null;
}
使用例は次のとおりです。
C#string? error = ValidateLength("こんにちは", 3, "名前");
if (error != null)
{
Console.WriteLine(error);
}
実行結果は次のようになります。
名前は3文字以内で入力してください。
全角半角を考慮した桁数チェックの例です。
C#using System.Text;
public static string? ValidateSjisLength(string? text, int maxLength, string fieldName)
{
if (string.IsNullOrEmpty(text))
{
return null;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
int length = sjis.GetByteCount(text);
if (length > maxLength)
{
return $"{fieldName}は全角{maxLength / 2}文字、または半角{maxLength}文字以内で入力してください。";
}
return null;
}
使用例です。
C#string? error = ValidateSjisLength("あいう", 5, "住所");
if (error != null)
{
Console.WriteLine(error);
}
実行結果は次のようになります。
住所は全角2文字、または半角5文字以内で入力してください。
ただし、最大桁数が奇数の場合、maxLength / 2では全角文字数の説明が分かりにくくなる場合があります。実際の業務では、エラーメッセージの文言も要件に合わせて調整しましょう。
6. 指定した桁数で文字列を切り出す方法
6-1. Substringで文字数ベースに切り出す
指定した文字数で文字列を切り出す場合は、Substringを使います。
C#string text = "こんにちは世界";
string result = text.Substring(0, 5);
Console.WriteLine(result);
実行結果は次のとおりです。
こんにちは
ただし、Substringで指定するのはバイト数ではなく、文字数ベースの位置と長さです。
C#string text = "ABCあいう";
string result = text.Substring(0, 4);
Console.WriteLine(result);
実行結果は次のようになります。
ABCあ
A、B、C、あの4文字が切り出されます。
指定文字数以内に丸めるメソッドは次のように書けます。
C#public static string TruncateByLength(string? text, int maxLength)
{
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
if (text.Length <= maxLength)
{
return text;
}
return text.Substring(0, maxLength);
}
使用例は次のとおりです。
C#Console.WriteLine(TruncateByLength("こんにちは世界", 5)); // こんにちは
Console.WriteLine(TruncateByLength("ABC", 5)); // ABC
C# 8.0以降では、範囲演算子を使って次のように書くこともできます。
C#string result = text[..maxLength];
ただし、maxLengthが文字列の長さを超えると例外になるため、事前チェックが必要です。
6-2. 全角半角を考慮して指定桁数で切り出す
全角を2桁、半角を1桁として指定桁数で切り出す場合は、文字ごとにバイト数を加算しながら処理すると安全です。
C#using System.Text;
public static string TruncateBySjisLength(string? text, int maxLength)
{
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
StringBuilder result = new StringBuilder();
int currentLength = 0;
foreach (char c in text)
{
int charLength = sjis.GetByteCount(c.ToString());
if (currentLength + charLength > maxLength)
{
break;
}
result.Append(c);
currentLength += charLength;
}
return result.ToString();
}
使用例です。
C#Console.WriteLine(TruncateBySjisLength("ABCあいう", 5));
実行結果は次のようになります。
ABCあ
ABCで3桁、あで2桁、合計5桁です。次のいを追加すると7桁になってしまうため、そこで切り出しを止めます。
別の例です。
C#Console.WriteLine(TruncateBySjisLength("あいうえお", 5));
実行結果は次のようになります。
あい
あいで4桁、次のうを追加すると6桁になり、最大5桁を超えるためです。
6-3. バイト数で切り出すときの注意点
バイト数で文字列を切り出す場合、単純にバイト配列を切り出すと文字化けする可能性があります。
たとえば、UTF-8の日本語は多くの場合3バイトです。バイト配列の途中で切ると、1文字を構成するバイト列が欠けてしまいます。
悪い例は次のようなコードです。
C#using System.Text;
string text = "あいう";
byte[] bytes = Encoding.UTF8.GetBytes(text);
byte[] cutBytes = bytes.Take(5).ToArray();
string result = Encoding.UTF8.GetString(cutBytes);
Console.WriteLine(result);
このように、バイト数だけで機械的に切ると、文字の途中で切れてしまう場合があります。
安全に切り出すには、文字単位でバイト数を確認しながら、上限を超えない範囲で追加していく方法が適しています。
C#using System.Text;
public static string TruncateByByteCount(string? text, int maxBytes, Encoding encoding)
{
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
StringBuilder result = new StringBuilder();
int currentBytes = 0;
foreach (char c in text)
{
string s = c.ToString();
int byteCount = encoding.GetByteCount(s);
if (currentBytes + byteCount > maxBytes)
{
break;
}
result.Append(c);
currentBytes += byteCount;
}
return result.ToString();
}
使用例です。
C#string text = "ABCあいう";
string result = TruncateByByteCount(text, 6, Encoding.UTF8);
Console.WriteLine(result);
UTF-8ではABCが3バイト、あが3バイトなので、結果は次のようになります。
ABCあ
6-4. 全角文字の途中で切れないようにする実装例
Shift_JISで全角文字の途中で切れないようにしたい場合も、文字単位でバイト数を確認しながら切り出します。
C#using System.Text;
public static string TruncateWithoutBreakingSjis(string? text, int maxBytes)
{
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
StringBuilder result = new StringBuilder();
int totalBytes = 0;
foreach (char c in text)
{
string current = c.ToString();
int currentBytes = sjis.GetByteCount(current);
if (totalBytes + currentBytes > maxBytes)
{
break;
}
result.Append(c);
totalBytes += currentBytes;
}
return result.ToString();
}
使用例です。
C#Console.WriteLine(TruncateWithoutBreakingSjis("ABCあいう", 6));
Shift_JISでは、ABCが3バイト、あが2バイトで合計5バイトです。次のいを追加すると7バイトになり、6バイトを超えるため、結果は次のようになります。
ABCあ
この方法なら、全角文字の途中で切れて文字化けするリスクを避けられます。
ただし、絵文字やサロゲートペアを含む場合、char単位のループでは不十分な場合があります。より厳密に処理したい場合は、テキスト要素単位で処理するなど、要件に応じた実装が必要です。
7. C#でstringの桁数を扱うときの注意点
7-1. Lengthは見た目の文字数と一致しない場合がある
string.Lengthは便利ですが、常に見た目の文字数と一致するわけではありません。
特に注意が必要なのは次のような文字です。
絵文字
サロゲートペア
結合文字
異体字セレクタを含む文字
複数のコードポイントで構成される文字
たとえば、絵文字は見た目では1文字でも、Lengthでは2以上になることがあります。
C#string text = "😀";
Console.WriteLine(text.Length);
実行結果は次のようになる場合があります。
2
ユーザーが画面上で見ている文字数を基準にしたい場合は、Lengthだけで判断すると違和感のある結果になることがあります。
見た目上の文字単位で数える場合は、次のようにStringInfoを使う方法があります。
C#using System.Globalization;
string text = "😀";
int count = new StringInfo(text).LengthInTextElements;
Console.WriteLine(count);
入力フォームで絵文字を許可する場合や、SNSのように見た目の文字数が重要な場合は、Lengthでよいかどうかを検討しましょう。
7-2. 改行・タブ・空白も文字数に含まれる
Lengthは、改行、タブ、空白も文字数としてカウントします。
C#string text = "ABC DEF";
Console.WriteLine(text.Length);
実行結果は次のとおりです。
7
ABCが3文字、空白が1文字、DEFが3文字なので、合計7文字です。
タブも1文字として数えられます。
C#string text = "ABC\tDEF";
Console.WriteLine(text.Length);
改行も文字数に含まれます。
C#string text = "ABC\nDEF";
Console.WriteLine(text.Length);
この場合、\nは1文字として扱われます。
Windowsの改行コードである\r\nを含む場合は、2文字として数えられます。
C#string text = "ABC\r\nDEF";
Console.WriteLine(text.Length);
このように、改行コードの種類によってLengthの値が変わることがあります。
テキストエリアの入力値やファイルの内容をチェックするときは、改行やタブも文字数に含めるのか、事前にルールを決めておくことが重要です。
7-3. Trimで前後の空白を除外してから数える
入力値の前後にある空白を除外してから桁数を数えたい場合は、Trimを使います。
C#string text = " Hello ";
Console.WriteLine(text.Length);
Console.WriteLine(text.Trim().Length);
実行結果は次のようになります。
9
5
元の文字列は、前後の空白を含めて9文字です。Trim()を使うと前後の空白が除去され、Helloの5文字になります。
入力チェックでは、次のように書くことが多いです。
C#string input = " Tanaka ";
string trimmed = input.Trim();
if (trimmed.Length <= 10)
{
Console.WriteLine("10文字以内です。");
}
nullの可能性がある場合は、次のようにします。
C#string? input = null;
int length = input?.Trim().Length ?? 0;
Console.WriteLine(length);
前後の空白を無視したいのか、それとも入力された空白も文字数に含めたいのかは、システムの仕様によって異なります。
たとえば、名前やメールアドレスでは前後の空白を除去してからチェックすることが多いです。一方、自由入力欄やメモ欄では、ユーザーが意図して入力した空白を残す場合もあります。
7-4. 入力フォーム・DB登録・帳票出力で基準を統一する
C#でstringの桁数を扱うときに重要なのは、どの基準で数えるかを統一することです。
たとえば、画面ではLengthで20文字以内としているのに、DBではUTF-8の20バイト以内、外部連携ではShift_JISの20バイト以内という仕様になっていると、入力できたはずの文字列が登録時や連携時にエラーになる可能性があります。
よくある基準は次のとおりです。
| 使用場面 | 推奨される基準 |
|---|---|
| 画面の文字数制限 | Lengthまたは見た目の文字数 |
| DBのバイト制限 | DBの文字コードに応じたバイト数 |
| 固定長ファイル | 仕様で指定された文字コードのバイト数 |
| 帳票出力 | 表示幅、全角半角幅 |
| 外部システム連携 | 連携仕様の文字コード・桁数 |
たとえば、入力フォームで「10文字以内」と表示するなら、ユーザーは全角も半角も1文字として理解することが多いです。この場合はLengthでチェックするのが自然です。
一方で、「全角10文字、半角20文字以内」と表示するなら、全角2桁・半角1桁としてチェックする必要があります。
仕様書や画面文言では、次のように明確にしておくと実装のずれを防げます。
名前は20文字以内で入力してください。
または、
名前は全角10文字、半角20文字以内で入力してください。
または、
名前はShift_JIS換算で20バイト以内で入力してください。
開発時には、画面、サーバー側バリデーション、DB、外部連携で同じ基準を使うようにしましょう。
8. よくある質問
8-1. C#でstringの桁数を取得するには?
C#でstringの桁数、つまり文字数を取得するには、Lengthを使います。
C#string text = "Hello";
int length = text.Length;
Console.WriteLine(length);
実行結果は次のとおりです。
5
日本語でも同じです。
C#string text = "こんにちは";
Console.WriteLine(text.Length);
実行結果は次のとおりです。
5
ただし、Lengthで取得できるのは基本的にchar数です。バイト数や全角半角を考慮した桁数とは異なります。
8-2. Lengthは全角を2文字として数える?
いいえ、Lengthは全角文字を2文字として数えません。
全角文字も半角文字も、基本的には1文字として数えます。
C#string half = "ABC";
string full = "ABC";
Console.WriteLine(half.Length);
Console.WriteLine(full.Length);
実行結果は次のとおりです。
3
3
全角を2桁、半角を1桁として数えたい場合は、Shift_JISのバイト数を使う方法があります。
C#using System.Text;
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string text = "ABCあいう";
Encoding sjis = Encoding.GetEncoding("shift_jis");
int length = sjis.GetByteCount(text);
Console.WriteLine(length);
実行結果は次のようになります。
9
8-3. 文字数とバイト数は何が違う?
文字数は、文字列に含まれる文字の数です。C#では主にLengthで取得します。
C#string text = "ABCあいう";
Console.WriteLine(text.Length);
実行結果は次のとおりです。
6
バイト数は、文字列を特定の文字コードで表現したときのデータサイズです。Encoding.GetByteCountで取得します。
C#using System.Text;
string text = "ABCあいう";
Console.WriteLine(Encoding.UTF8.GetByteCount(text));
実行結果は次のようになります。
12
同じ文字列でも、UTF-8、Shift_JIS、UTF-16など、文字コードによってバイト数は変わります。
8-4. 全角半角を区別して桁数を数えるには?
全角を2桁、半角を1桁として数えたい場合は、Shift_JISのバイト数を使う方法がよく使われます。
C#using System.Text;
public static int GetSjisLength(string? text)
{
if (string.IsNullOrEmpty(text))
{
return 0;
}
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding sjis = Encoding.GetEncoding("shift_jis");
return sjis.GetByteCount(text);
}
使用例です。
C#Console.WriteLine(GetSjisLength("ABC")); // 3
Console.WriteLine(GetSjisLength("あいう")); // 6
Console.WriteLine(GetSjisLength("ABCあいう")); // 9
ただし、Shift_JISで表現できない文字をどう扱うかは、システム要件によって変わります。絵文字や特殊文字を許可する場合は、別途ルールを決めておくと安全です。
8-5. nullの文字列でLengthを使うとどうなる?
nullの文字列に対してLengthを使うと、NullReferenceExceptionが発生します。
C#string text = null;
Console.WriteLine(text.Length);
このコードは実行時エラーになります。
nullの可能性がある場合は、次のようにチェックしましょう。
C#string? text = null;
int length = text?.Length ?? 0;
Console.WriteLine(length);
実行結果は次のとおりです。
0
また、空文字とnullをまとめて扱いたい場合は、string.IsNullOrEmptyを使います。
C#string? text = null;
if (string.IsNullOrEmpty(text))
{
Console.WriteLine("文字列は空です。");
}
空白だけの文字列も空扱いにしたい場合は、string.IsNullOrWhiteSpaceを使います。
C#string? text = " ";
if (string.IsNullOrWhiteSpace(text))
{
Console.WriteLine("文字列は空または空白のみです。");
}
まとめ
C#でstringの桁数を取得する基本は、Lengthを使うことです。
C#string text = "Hello";
int length = text.Length;
Lengthは文字列に含まれるchar数を返します。日本語や英数字、記号の多くは1文字として数えられるため、通常の文字数チェックではLengthを使えば十分です。
ただし、Lengthは全角を2文字として数えるわけではありません。また、バイト数を取得するものでもありません。
用途ごとに使い分けると、次のようになります。
| やりたいこと | 使う方法 |
|---|---|
| 文字数を取得したい | text.Length |
| nullでも安全に文字数を取得したい | text?.Length ?? 0 |
| UTF-8のバイト数を取得したい | Encoding.UTF8.GetByteCount(text) |
| Shift_JISのバイト数を取得したい | Encoding.GetEncoding("shift_jis").GetByteCount(text) |
| 全角2桁・半角1桁で数えたい | Shift_JISのバイト数、または独自の幅判定 |
| 指定文字数で切り出したい | Substring |
| 指定バイト数で安全に切り出したい | 文字単位でバイト数を加算して切り出す |
入力フォーム、DB登録、帳票出力、外部システム連携では、それぞれ求められる「桁数」の意味が異なることがあります。
「文字数」なのか、「全角半角を考慮した桁数」なのか、「特定の文字コードでのバイト数」なのかを明確にし、要件に合った方法で実装することが重要です。

