C#の文字と文字列を基礎から解説|char・stringの違いと使い方

はじめに

C#でプログラミングを始めると、早い段階で「文字」と「文字列」という言葉に出会います。どちらもテキストを扱うためのものですが、C#では1文字を扱うcharと、文字の並びを扱うstringが明確に区別されています。

たとえば、アルファベットのAや数字の1、ひらがなののような1つの文字を扱う場合はcharを使います。一方で、Helloこんにちはのように複数の文字をまとめて扱う場合はstringを使います。

この違いを理解しないままコードを書くと、シングルクォーテーションとダブルクォーテーションを間違えたり、charに複数文字を代入しようとしてエラーになったりします。

この記事では、C#の文字と文字列について、charstringの違い、基本的な使い方、変換方法、文字列操作、日本語やUnicode文字を扱う際の注意点まで、基礎からわかりやすく解説します。

1. C#における「文字」と「文字列」の基本

1-1. C#で扱う文字とは何か

C#における「文字」とは、1つの文字を表すデータのことです。たとえば、次のようなものが文字です。

C#
'A'
'あ'
'1'
'@'

C#では、1文字を扱うためにchar型を使います。charは「character」の略で、1つの文字を表す型です。

C#
char letter = 'A';
char japanese = 'あ';
char number = '1';

ここで注意したいのは、'1'は数値の1ではなく、文字としての1だという点です。数値計算に使うint型の1とは別物です。

C#
int numberValue = 1;
char numberChar = '1';

見た目は似ていますが、C#では型が異なるため、扱い方も変わります。

1-2. 文字列とは何か

文字列とは、文字が複数並んだデータのことです。C#では文字列を扱うためにstring型を使います。

C#
string message = "Hello";
string greeting = "こんにちは";
string name = "田中";

stringは、内部的には複数の文字が並んだものとして扱われます。たとえば、"Hello"は次のような5つの文字から構成されています。

C#
'H', 'e', 'l', 'l', 'o'

つまり、charは1文字、stringは文字の集まりと考えると理解しやすいです。

1-3. charとstringを最初に区別すべき理由

C#では、charstringの違いをあいまいにすると、すぐにコンパイルエラーが発生します。

たとえば、charには1文字しか入れられません。

C#
char c = 'A';

これは正しい書き方です。しかし、次のように複数文字を代入しようとするとエラーになります。

C#
char c = 'AB'; // エラー

また、charはシングルクォーテーション、stringはダブルクォーテーションで囲む必要があります。

C#
char c = 'A';
string s = "A";

どちらも見た目はAですが、型が違います。'A'char"A"stringです。

1-4. 「c# 文字」で検索する人がつまずきやすいポイント

「c# 文字」で検索する人がつまずきやすいポイントには、次のようなものがあります。

C#
char c = "A";   // エラー
string s = 'A'; // エラー

charにはシングルクォーテーション、stringにはダブルクォーテーションを使う必要があります。

また、文字列から1文字を取り出したときの型にも注意が必要です。

C#
string text = "Hello";
char first = text[0];

text[0]で取得できるのはstringではなくcharです。文字列の一部を取り出す場合でも、1文字だけならcharとして扱われます。

このように、C#では文字と文字列の区別が明確です。基礎を理解しておくことで、文字列操作や入力処理でのエラーを減らせます。

2. char型の基本と使い方

2-1. char型とは

char型は、C#で1つの文字を表すための型です。アルファベット、日本語、数字の文字、記号など、1文字であればcharとして扱えます。

C#
char alphabet = 'A';
char hiragana = 'あ';
char symbol = '#';

char型は、文字そのものを扱いたいときに使います。たとえば、ユーザーが入力した文字を1文字ずつ調べる場合や、特定の文字と一致するか判定する場合に便利です。

2-2. char型の宣言と代入

char型の変数は、次のように宣言します。

C#
char c;

値を代入する場合は、1文字をシングルクォーテーションで囲みます。

C#
char c = 'A';

あとから値を代入することもできます。

C#
char c;
c = 'B';

日本語の1文字も代入できます。

C#
char kana = 'か';

ただし、複数文字は代入できません。

C#
char word = 'かな'; // エラー

この場合はstring型を使います。

C#
string word = "かな";

2-3. シングルクォーテーションで文字を表す

C#では、char型の値はシングルクォーテーションで囲みます。

C#
char c = 'A';

ダブルクォーテーションを使うと、charではなくstringとして扱われます。

C#
char c = "A"; // エラー

"A"は1文字に見えますが、C#では文字列です。そのため、char型の変数には代入できません。

正しくは次のように書きます。

C#
char c = 'A';

2-4. char型で扱える文字の例

char型では、さまざまな1文字を扱えます。

C#
char upper = 'A';
char lower = 'a';
char digit = '5';
char hiragana = 'あ';
char kanji = '漢';
char mark = '!';

数字の文字もcharとして扱えます。

C#
char digit = '9';

ただし、これは数値の9ではありません。計算にはそのまま使えないため、必要に応じて変換します。

C#
char digit = '9';
int number = digit - '0';

Console.WriteLine(number); // 9

2-5. char型でよくあるエラーと原因

char型でよくあるエラーの1つは、複数文字を代入しようとすることです。

C#
char c = 'AB'; // エラー

charは1文字専用の型なので、ABのような複数文字は扱えません。この場合はstringを使います。

C#
string s = "AB";

もう1つのよくあるエラーは、クォーテーションの種類を間違えることです。

C#
char c = "A"; // エラー

charではなくstringとして書かれているため、型が一致しません。

また、空の文字をcharに代入することもできません。

C#
char c = ''; // エラー

空を表したい場合は、stringの空文字を使うか、char?を使ってnullを許可します。

C#
string empty = "";
char? nullableChar = null;

3. string型の基本と使い方

3-1. string型とは

string型は、C#で文字列を扱うための型です。文字列とは、0文字以上の文字が並んだデータです。

C#
string text = "Hello";
string message = "こんにちは";

stringは複数文字を扱うだけでなく、1文字だけの文字列や空文字も扱えます。

C#
string one = "A";
string empty = "";

"A"は1文字だけですが、型はcharではなくstringです。この点は初心者が混乱しやすい部分です。

3-2. string型の宣言と代入

string型の変数は、次のように宣言します。

C#
string name;

値を代入する場合は、文字列をダブルクォーテーションで囲みます。

C#
string name = "Sato";

日本語の文字列も扱えます。

C#
string greeting = "こんにちは";

あとから別の文字列を代入することもできます。

C#
string message = "Hello";
message = "Good morning";

3-3. ダブルクォーテーションで文字列を表す

C#では、string型の値はダブルクォーテーションで囲みます。

C#
string text = "Hello";

シングルクォーテーションを使うとcharとして扱われるため、string型にはそのまま代入できません。

C#
string text = 'A'; // エラー

1文字だけの文字列を作りたい場合でも、string型ならダブルクォーテーションを使います。

C#
string text = "A";

3-4. 空文字とnullの違い

stringを扱うときに重要なのが、空文字とnullの違いです。

空文字は、文字数が0の文字列です。

C#
string empty = "";

これは文字列オブジェクト自体は存在していますが、中身の文字がない状態です。

一方、nullは文字列そのものが存在しない状態です。

C#
string value = null;

空文字とnullは別物です。

C#
string empty = "";
string value = null;

Console.WriteLine(empty.Length); // 0
Console.WriteLine(value.Length); // エラー

nullの変数に対してLengthを使うと、NullReferenceExceptionが発生します。

空文字またはnullをまとめて判定したい場合は、string.IsNullOrEmptyを使います。

C#
string text = "";

if (string.IsNullOrEmpty(text))
{
Console.WriteLine("空またはnullです");
}

空白だけの文字列も含めて判定したい場合は、string.IsNullOrWhiteSpaceを使います。

C#
string text = "   ";

if (string.IsNullOrWhiteSpace(text))
{
Console.WriteLine("空白のみ、空文字、またはnullです");
}

3-5. string型でよくあるエラーと注意点

string型でよくあるエラーは、nullに対してメソッドやプロパティを呼び出すことです。

C#
string text = null;
Console.WriteLine(text.Length); // NullReferenceException

このようなエラーを防ぐには、事前にnullチェックを行います。

C#
string text = null;

if (text != null)
{
Console.WriteLine(text.Length);
}

また、文字列は変更可能に見えて、実際には変更不可です。たとえば次のコードでは、元の文字列が直接書き換わっているわけではありません。

C#
string text = "Hello";
text = text + " World";

この場合、新しい文字列が作られ、textがその新しい文字列を参照するようになります。文字列の結合を大量に行う場合は、StringBuilderの使用を検討します。

4. charとstringの違い

4-1. 1文字を扱うcharと複数文字を扱うstring

charstringの最も大きな違いは、扱える文字数です。

charは1文字だけを扱います。

C#
char c = 'A';

stringは0文字以上の文字を扱います。

C#
string s1 = "A";
string s2 = "Hello";
string s3 = "";

stringは1文字だけでも使えますが、型としてはcharとは異なります。

C#
char c = 'A';
string s = "A";

4-2. シングルクォーテーションとダブルクォーテーションの違い

charはシングルクォーテーションで囲みます。

C#
char c = 'A';

stringはダブルクォーテーションで囲みます。

C#
string s = "A";

この違いを間違えるとコンパイルエラーになります。

C#
char c = "A";   // エラー
string s = 'A'; // エラー

C#では、引用符の種類によって文字なのか文字列なのかが決まります。

4-3. メモリ上の扱いと変更可否の違い

charは値型です。変数には文字の値そのものが格納されるイメージです。

C#
char c = 'A';

一方、stringは参照型です。文字列データへの参照を変数が持つイメージです。

C#
string text = "Hello";

また、stringは不変です。一度作成された文字列の中身は変更できません。

C#
string text = "Hello";
text = text.Replace("H", "J");

Console.WriteLine(text); // Jello

このコードでは、元の"Hello"が直接変更されたのではなく、"Jello"という新しい文字列が作られています。

4-4. charとstringの使い分け

1文字だけを扱いたい場合はcharを使います。

C#
char initial = 'T';

文字の並びを扱いたい場合はstringを使います。

C#
string name = "Tanaka";

文字列の中から1文字ずつ処理したい場合は、stringからcharを取り出して使います。

C#
string text = "ABC";

foreach (char c in text)
{
Console.WriteLine(c);
}

ユーザー名、メッセージ、住所、メールアドレスなどは通常stringで扱います。性別コードや区分コードなど、1文字で意味を持つデータはcharで扱うことがあります。

4-5. charとstringの比較表

項目charstring
扱う内容1文字0文字以上の文字列
囲み方シングルクォーテーションダブルクォーテーション
'A'"A", "Hello"
型の種類値型参照型
空の値''は不可""が使える
null通常は不可、char?なら可
主な用途1文字の比較、文字単位の処理名前、文章、メッセージなどの文字列処理

5. 文字と文字列の変換方法

5-1. charをstringに変換する方法

charstringに変換するには、ToStringメソッドを使うのが基本です。

C#
char c = 'A';
string s = c.ToString();

Console.WriteLine(s); // A

また、stringのコンストラクタを使って変換することもできます。

C#
char c = 'A';
string s = new string(c, 1);

Console.WriteLine(s); // A

ただし、1文字を文字列に変換するだけならToStringが簡単です。

5-2. stringからcharを取り出す方法

stringから1文字を取り出すには、インデックスを使います。

C#
string text = "Hello";
char first = text[0];

Console.WriteLine(first); // H

C#の文字列インデックスは0から始まります。

C#
string text = "Hello";

Console.WriteLine(text[0]); // H
Console.WriteLine(text[1]); // e
Console.WriteLine(text[2]); // l

最後の文字を取得するには、Length - 1を使います。

C#
string text = "Hello";
char last = text[text.Length - 1];

Console.WriteLine(last); // o

5-3. ToStringメソッドを使った変換

ToStringは、charだけでなく、数値や日付などを文字列に変換するときにも使われます。

C#
char c = 'A';
string text = c.ToString();

数値を文字列にする場合も同じです。

C#
int number = 123;
string text = number.ToString();

Console.WriteLine(text); // 123

charを文字列として連結したい場合にも便利です。

C#
char c = 'A';
string result = "文字は" + c.ToString();

Console.WriteLine(result); // 文字はA

なお、文字列連結ではcharが自動的に文字列として扱われる場合もあります。

C#
char c = 'A';
string result = "文字は" + c;

Console.WriteLine(result); // 文字はA

5-4. char配列とstringの相互変換

複数のcharを配列として扱い、それをstringに変換することもできます。

C#
char[] chars = { 'H', 'e', 'l', 'l', 'o' };
string text = new string(chars);

Console.WriteLine(text); // Hello

逆に、stringchar配列に変換するにはToCharArrayを使います。

C#
string text = "Hello";
char[] chars = text.ToCharArray();

Console.WriteLine(chars[0]); // H

文字列を1文字ずつ加工したい場合、char配列に変換すると扱いやすくなることがあります。

C#
string text = "cat";
char[] chars = text.ToCharArray();

chars[0] = 'b';

string result = new string(chars);
Console.WriteLine(result); // bat

5-5. 変換時に注意すべき例外

stringからcharを取り出すときは、文字列が空でないことを確認する必要があります。

C#
string text = "";
char c = text[0]; // エラー

空文字には0番目の文字が存在しないため、IndexOutOfRangeExceptionが発生します。

安全に取り出すには、Lengthを確認します。

C#
string text = "";

if (text.Length > 0)
{
char c = text[0];
Console.WriteLine(c);
}
else
{
Console.WriteLine("文字列は空です");
}

nullの可能性がある場合は、string.IsNullOrEmptyを使うと安全です。

C#
string text = null;

if (!string.IsNullOrEmpty(text))
{
char c = text[0];
Console.WriteLine(c);
}

6. C#で文字列を操作する基本

6-1. 文字列の長さを取得する

文字列の長さを取得するには、Lengthプロパティを使います。

C#
string text = "Hello";
int length = text.Length;

Console.WriteLine(length); // 5

日本語の文字列でも使えます。

C#
string text = "こんにちは";
Console.WriteLine(text.Length); // 5

ただし、絵文字や一部の特殊な文字では、見た目の文字数とLengthの値が一致しない場合があります。この点はUnicodeの扱いで注意が必要です。

6-2. 文字列から特定の文字を取得する

文字列から特定の位置の文字を取得するには、インデックスを使います。

C#
string text = "Hello";

char first = text[0];
char second = text[1];

Console.WriteLine(first); // H
Console.WriteLine(second); // e

インデックスは0から始まるため、1文字目は0、2文字目は1です。

範囲外のインデックスを指定するとエラーになります。

C#
string text = "Hello";
char c = text[10]; // エラー

安全にアクセスするには、Lengthを使って範囲を確認します。

C#
string text = "Hello";
int index = 2;

if (index >= 0 && index < text.Length)
{
Console.WriteLine(text[index]);
}

6-3. 文字列を連結する

文字列を連結するには、+演算子を使います。

C#
string firstName = "Taro";
string lastName = "Yamada";

string fullName = lastName + " " + firstName;

Console.WriteLine(fullName); // Yamada Taro

複数の文字列を連結する場合は、string.Concatも使えます。

C#
string result = string.Concat("A", "B", "C");

Console.WriteLine(result); // ABC

読みやすさを重視するなら、文字列補間もよく使われます。

C#
string name = "Taro";
int age = 20;

string message = $"{name}さんは{age}歳です。";

Console.WriteLine(message);

6-4. 文字列を置換する

文字列の一部を置換するには、Replaceメソッドを使います。

C#
string text = "Hello";
string result = text.Replace("H", "J");

Console.WriteLine(result); // Jello

単語を置換することもできます。

C#
string text = "I like cats.";
string result = text.Replace("cats", "dogs");

Console.WriteLine(result); // I like dogs.

Replaceは元の文字列を変更するのではなく、新しい文字列を返します。

C#
string text = "Hello";
text.Replace("H", "J");

Console.WriteLine(text); // Hello

結果を使いたい場合は、戻り値を変数に代入します。

C#
text = text.Replace("H", "J");

6-5. 文字列を分割する

文字列を分割するには、Splitメソッドを使います。

C#
string csv = "apple,banana,orange";
string[] fruits = csv.Split(',');

foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
}

実行結果は次のようになります。

C#
apple
banana
orange

スペースで分割することもできます。

C#
string text = "C# is fun";
string[] words = text.Split(' ');

foreach (string word in words)
{
Console.WriteLine(word);
}

6-6. 文字列の一部を取り出す

文字列の一部を取り出すには、Substringメソッドを使います。

C#
string text = "Hello World";
string part = text.Substring(0, 5);

Console.WriteLine(part); // Hello

第1引数は開始位置、第2引数は取り出す文字数です。

C#
string text = "Hello World";

string hello = text.Substring(0, 5);
string world = text.Substring(6, 5);

Console.WriteLine(hello); // Hello
Console.WriteLine(world); // World

指定範囲が文字列の長さを超えるとエラーになるため、範囲には注意が必要です。

7. C#で文字や文字列を比較・検索する方法

7-1. char同士を比較する

char同士を比較するには、==演算子を使います。

C#
char c = 'A';

if (c == 'A')
{
Console.WriteLine("Aです");
}

一致しないことを確認するには、!=を使います。

C#
char c = 'B';

if (c != 'A')
{
Console.WriteLine("Aではありません");
}

文字が数字かどうか、英字かどうかを判定したい場合は、charクラスのメソッドを使えます。

C#
char c = '5';

if (char.IsDigit(c))
{
Console.WriteLine("数字です");
}
C#
char c = 'A';

if (char.IsLetter(c))
{
Console.WriteLine("文字です");
}

7-2. string同士を比較する

string同士を比較する場合も、==演算子を使えます。

C#
string a = "Hello";
string b = "Hello";

if (a == b)
{
Console.WriteLine("同じ文字列です");
}

Equalsメソッドを使うこともできます。

C#
string a = "Hello";
string b = "Hello";

if (a.Equals(b))
{
Console.WriteLine("同じ文字列です");
}

ただし、anullの場合、a.Equals(b)NullReferenceExceptionになる可能性があります。安全に比較したい場合は、string.Equalsを使う方法があります。

C#
string a = null;
string b = "Hello";

if (string.Equals(a, b))
{
Console.WriteLine("同じです");
}
else
{
Console.WriteLine("違います");
}

7-3. Containsで文字列に含まれるか判定する

文字列の中に特定の文字列が含まれているかを調べるには、Containsを使います。

C#
string text = "Hello World";

if (text.Contains("World"))
{
Console.WriteLine("Worldが含まれています");
}

1文字が含まれているかを調べることもできます。

C#
string text = "Hello";

if (text.Contains('e'))
{
Console.WriteLine("eが含まれています");
}

検索対象がnullの場合はエラーになるため、事前に確認しておくと安全です。

C#
string text = null;

if (!string.IsNullOrEmpty(text) && text.Contains("A"))
{
Console.WriteLine("Aが含まれています");
}

7-4. IndexOfで文字の位置を調べる

文字列の中で、特定の文字や文字列が何番目にあるか調べるには、IndexOfを使います。

C#
string text = "Hello";
int index = text.IndexOf('e');

Console.WriteLine(index); // 1

見つからない場合は-1が返されます。

C#
string text = "Hello";
int index = text.IndexOf('z');

Console.WriteLine(index); // -1

文字列を検索することもできます。

C#
string text = "Hello World";
int index = text.IndexOf("World");

Console.WriteLine(index); // 6

IndexOfは、含まれているかどうかと位置を同時に確認したいときに便利です。

C#
string text = "Hello World";
int index = text.IndexOf("World");

if (index >= 0)
{
Console.WriteLine($"見つかりました。位置: {index}");
}

7-5. 大文字・小文字を区別しない比較方法

通常の比較では、大文字と小文字は別の文字として扱われます。

C#
string a = "hello";
string b = "HELLO";

Console.WriteLine(a == b); // False

大文字・小文字を区別せずに比較したい場合は、string.Equalsに比較方法を指定します。

C#
string a = "hello";
string b = "HELLO";

bool result = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);

Console.WriteLine(result); // True

Containsで大文字・小文字を区別しない検索をしたい場合は、比較方法を指定します。

C#
string text = "Hello World";

bool result = text.Contains("hello", StringComparison.OrdinalIgnoreCase);

Console.WriteLine(result); // True

古い環境でこの書き方が使えない場合は、両方を大文字または小文字に変換して比較する方法もあります。

C#
string text = "Hello World";

bool result = text.ToLower().Contains("hello");

Console.WriteLine(result); // True

ただし、文化圏による文字の扱いを避けたい場合は、StringComparison.OrdinalIgnoreCaseを使うのが一般的です。

8. 特殊文字・エスケープシーケンスの扱い

8-1. 改行やタブを文字列に含める方法

C#では、文字列の中に改行やタブなどの特殊文字を含めるために、エスケープシーケンスを使います。

改行は\nで表します。

C#
string text = "1行目\n2行目";

Console.WriteLine(text);

実行結果は次のようになります。

C#
1行目
2行目

タブは\tで表します。

C#
string text = "名前\t年齢";
Console.WriteLine(text);

8-2. ダブルクォーテーションを文字列内で使う方法

文字列の中にダブルクォーテーションを含めたい場合は、\"を使います。

C#
string text = "彼は\"こんにちは\"と言いました。";

Console.WriteLine(text);

実行結果は次のようになります。

C#
彼は"こんにちは"と言いました。

ダブルクォーテーションは文字列の開始と終了にも使われるため、そのまま書くとエラーになります。

C#
string text = "彼は"こんにちは"と言いました。"; // エラー

8-3. バックスラッシュを扱う方法

バックスラッシュを文字列に含めたい場合は、\\と書きます。

C#
string path = "C:\\Users\\Taro\\Documents";

Console.WriteLine(path);

実行結果は次のようになります。

C#
C:\Users\Taro\Documents

ファイルパスを書くときによく使います。

8-4. 逐語的文字列リテラルの使い方

バックスラッシュが多い文字列では、逐語的文字列リテラルを使うと読みやすくなります。文字列の前に@を付けます。

C#
string path = @"C:\Users\Taro\Documents";

Console.WriteLine(path);

逐語的文字列リテラルでは、バックスラッシュをエスケープする必要がありません。

複数行の文字列も書けます。

C#
string text = @"1行目
2行目
3行目";

Console.WriteLine(text);

ただし、逐語的文字列リテラル内でダブルクォーテーションを使う場合は、""と2つ重ねます。

C#
string text = @"彼は""こんにちは""と言いました。";

8-5. 文字列補間を使った書き方

文字列の中に変数の値を埋め込むには、文字列補間を使います。文字列の前に$を付け、埋め込みたい変数や式を{}で囲みます。

C#
string name = "Taro";
int age = 20;

string message = $"{name}さんは{age}歳です。";

Console.WriteLine(message);

計算式を埋め込むこともできます。

C#
int price = 1000;
int count = 3;

string message = $"合計金額は{price * count}円です。";

Console.WriteLine(message);

逐語的文字列リテラルと組み合わせることもできます。

C#
string user = "Taro";
string path = $@"C:\Users\{user}\Documents";

Console.WriteLine(path);

9. 日本語やUnicode文字を扱うときの注意点

9-1. C#のcharはUnicode文字を扱う

C#のcharはUnicode文字を扱うための型です。英数字だけでなく、日本語や記号も扱えます。

C#
char c1 = 'A';
char c2 = 'あ';
char c3 = '漢';

ただし、C#のcharは「見た目上の1文字」と常に一致するわけではありません。特に絵文字や一部の特殊な文字では注意が必要です。

9-2. 日本語文字をcharやstringで扱う方法

日本語の1文字はcharで扱えます。

C#
char kana = 'あ';
char kanji = '漢';

日本語の文字列はstringで扱います。

C#
string message = "こんにちは";
string name = "山田太郎";

文字列から日本語の1文字を取り出すこともできます。

C#
string text = "こんにちは";
char first = text[0];

Console.WriteLine(first); // こ

ひらがな、カタカナ、漢字など、多くの日本語文字はこのように自然に扱えます。

9-3. サロゲートペアとは

C#のcharは16ビットのUnicodeコード単位を表します。そのため、Unicodeの中には1つのcharでは表せない文字があります。

そのような文字は、2つのcharを組み合わせて表されます。これをサロゲートペアといいます。

たとえば、絵文字などはサロゲートペアになることがあります。

C#
string emoji = "😀";

Console.WriteLine(emoji.Length); // 2

見た目は1文字の絵文字ですが、Lengthは2になる場合があります。これは、内部的に2つのcharで表されているためです。

9-4. 絵文字や特殊な文字で注意すべきこと

絵文字や一部の特殊文字を扱うときは、Lengthやインデックスアクセスに注意が必要です。

C#
string emoji = "😀";

Console.WriteLine(emoji[0]);
Console.WriteLine(emoji[1]);

このように1つずつ取り出すと、見た目の絵文字として正しく扱えない場合があります。

絵文字を含む文字列を「見た目上の文字」単位で扱いたい場合は、単純なchar単位の処理では不十分なことがあります。通常の英数字や日本語の多くはchar単位で処理できますが、絵文字や結合文字を扱うアプリではUnicodeの仕様を意識する必要があります。

9-5. 文字化けを防ぐための基本

文字化けを防ぐには、文字コードを正しく扱うことが大切です。C#の文字列自体はUnicodeとして扱われますが、ファイルの読み書きや外部システムとの通信ではエンコーディングの指定が重要になります。

たとえば、UTF-8でファイルを書き出す場合は次のようにします。

C#
using System.Text;

string text = "こんにちは";
File.WriteAllText("sample.txt", text, Encoding.UTF8);

読み込むときも同じエンコーディングを指定します。

C#
using System.Text;

string text = File.ReadAllText("sample.txt", Encoding.UTF8);
Console.WriteLine(text);

Web API、CSVファイル、ログファイルなどを扱う場合は、どの文字コードで保存・送受信されているかを確認することが重要です。

10. よくある疑問とトラブル対処

10-1. charに複数文字を入れられない理由

charは1文字を表す型なので、複数文字を入れることはできません。

C#
char c = 'AB'; // エラー

ABは2文字なので、stringを使います。

C#
string s = "AB";

1文字だけならcharで扱えます。

C#
char c = 'A';

charstringは見た目が似ていても別の型です。1文字だけなら必ずcharを使うべきというわけではなく、データの意味によって使い分けます。名前やコード、メッセージなど、文字列として扱う可能性があるものはstringにすることが多いです。

10-2. stringの1文字目を取得する方法

stringの1文字目を取得するには、インデックス0を指定します。

C#
string text = "Hello";
char first = text[0];

Console.WriteLine(first); // H

ただし、文字列が空の場合はエラーになります。

C#
string text = "";
char first = text[0]; // エラー

安全に取得するには、空文字やnullを確認します。

C#
string text = "Hello";

if (!string.IsNullOrEmpty(text))
{
char first = text[0];
Console.WriteLine(first);
}

10-3. 文字列が空かどうか判定する方法

文字列が空かどうかを判定するには、Lengthを使えます。

C#
string text = "";

if (text.Length == 0)
{
Console.WriteLine("空文字です");
}

ただし、textnullの場合はエラーになります。

より安全に判定するには、string.IsNullOrEmptyを使います。

C#
string text = "";

if (string.IsNullOrEmpty(text))
{
Console.WriteLine("空またはnullです");
}

空白だけの文字列も空とみなしたい場合は、string.IsNullOrWhiteSpaceを使います。

C#
string text = "   ";

if (string.IsNullOrWhiteSpace(text))
{
Console.WriteLine("空白のみ、空文字、またはnullです");
}

10-4. null参照エラーを防ぐ方法

stringnullになる可能性があります。nullに対してLengthContainsなどを呼び出すと、NullReferenceExceptionが発生します。

C#
string text = null;
Console.WriteLine(text.Length); // エラー

防ぐには、事前にnullチェックを行います。

C#
string text = null;

if (text != null)
{
Console.WriteLine(text.Length);
}

より簡潔に書くなら、null条件演算子を使えます。

C#
string text = null;

Console.WriteLine(text?.Length);

text?.Lengthは、textnullの場合に例外を出さず、nullを返します。

既定値を使いたい場合は、null合体演算子を使います。

C#
string text = null;
string result = text ?? "";

Console.WriteLine(result.Length); // 0

10-5. 文字列結合が多いときの対処法

少数の文字列結合であれば、+演算子で問題ありません。

C#
string message = "Hello" + " " + "World";

しかし、ループの中で大量に文字列を結合する場合は、毎回新しい文字列が作られるため効率が悪くなることがあります。

C#
string result = "";

for (int i = 0; i < 1000; i++)
{
result += i.ToString();
}

このような場合は、StringBuilderを使うと効率的です。

C#
using System.Text;

StringBuilder builder = new StringBuilder();

for (int i = 0; i < 1000; i++)
{
builder.Append(i);
}

string result = builder.ToString();

文字列を何度も追加・変更する処理では、StringBuilderの利用を検討しましょう。

11. C#の文字と文字列を使った実践例

11-1. 入力された文字列を1文字ずつ処理する

入力された文字列を1文字ずつ処理するには、foreachを使うと簡単です。

C#
string input = "Hello";

foreach (char c in input)
{
Console.WriteLine(c);
}

実行結果は次のようになります。

C#
H
e
l
l
o

文字が数字かどうかを判定する例です。

C#
string input = "A1B2C3";

foreach (char c in input)
{
if (char.IsDigit(c))
{
Console.WriteLine($"{c} は数字です");
}
}

このように、文字列はcharの集まりとして処理できます。

11-2. 特定の文字を含むか判定する

文字列に特定の文字が含まれているかを判定するには、Containsを使います。

C#
string text = "programming";

if (text.Contains('g'))
{
Console.WriteLine("gが含まれています");
}

特定の単語が含まれているかも判定できます。

C#
string text = "C# programming is fun";

if (text.Contains("programming"))
{
Console.WriteLine("programmingが含まれています");
}

位置も知りたい場合は、IndexOfを使います。

C#
string text = "programming";
int index = text.IndexOf('g');

if (index >= 0)
{
Console.WriteLine($"gは{index}番目にあります");
}

11-3. 文字列を整形して表示する

文字列補間を使うと、変数の値をわかりやすく埋め込めます。

C#
string name = "Yamada";
int score = 85;

string message = $"{name}さんの点数は{score}点です。";

Console.WriteLine(message);

桁数や小数点以下の表示を整えることもできます。

C#
double price = 1234.5;

Console.WriteLine($"{price:F2}"); // 1234.50

日付を整形して表示する例です。

C#
DateTime today = DateTime.Now;

Console.WriteLine($"{today:yyyy年MM月dd日}");

文字列補間は、読みやすく保守しやすいコードを書くうえで便利です。

11-4. char配列を使って文字列を作成する

char配列から文字列を作るには、new stringを使います。

C#
char[] chars = { 'C', '#', '入', '門' };
string text = new string(chars);

Console.WriteLine(text); // C#入門

文字列を一度char配列に変換し、文字を変更してから再び文字列に戻すこともできます。

C#
string text = "cat";
char[] chars = text.ToCharArray();

chars[0] = 'b';

string result = new string(chars);

Console.WriteLine(result); // bat

stringは不変なので、文字列の一部を直接変更することはできません。

C#
string text = "cat";
text[0] = 'b'; // エラー

変更したい場合は、char配列やStringBuilderを使います。

11-5. StringBuilderを使って効率よく文字列を組み立てる

大量の文字列を組み立てる場合は、StringBuilderを使うと効率的です。

C#
using System.Text;

StringBuilder builder = new StringBuilder();

builder.Append("C#");
builder.Append("の");
builder.Append("文字列");
builder.Append("を学習します。");

string result = builder.ToString();

Console.WriteLine(result);

ループで文字列を作る場合にも便利です。

C#
using System.Text;

StringBuilder builder = new StringBuilder();

for (int i = 1; i <= 5; i++)
{
builder.AppendLine($"{i}行目です");
}

string result = builder.ToString();

Console.WriteLine(result);

AppendLineを使うと、改行付きで文字列を追加できます。ログ、CSV、レポート、HTMLの生成など、文字列を何度も追加する処理ではStringBuilderが役立ちます。

まとめ

C#で文字や文字列を扱うときは、まずcharstringの違いを理解することが重要です。charは1文字を扱う型で、シングルクォーテーションを使って表します。一方、stringは0文字以上の文字列を扱う型で、ダブルクォーテーションを使って表します。

C#
char c = 'A';
string s = "A";

見た目は似ていても、'A'char"A"stringです。この違いを理解しておくと、C#の文字処理で発生しやすいエラーを避けやすくなります。

また、文字列から1文字を取り出すにはインデックスを使い、charstringに変換するにはToStringを使います。文字列の検索、置換、分割、連結には、ContainsIndexOfReplaceSplitなどのメソッドが役立ちます。

日本語は通常のcharstringで扱えますが、絵文字や一部のUnicode文字では、見た目の1文字とcharの数が一致しない場合があります。文字化けを防ぐには、ファイル入出力や通信時のエンコーディングにも注意しましょう。

C#の文字と文字列は、コンソールアプリ、Webアプリ、業務システム、ゲーム開発など、あらゆる場面で使います。charstringの基礎をしっかり押さえておくことで、文字列操作をより正確に、効率よく書けるようになります。