C#の文字と文字列を基礎から解説|char・stringの違いと使い方
はじめに
C#でプログラミングを始めると、早い段階で「文字」と「文字列」という言葉に出会います。どちらもテキストを扱うためのものですが、C#では1文字を扱うchar型と、文字の並びを扱うstring型が明確に区別されています。
たとえば、アルファベットのAや数字の1、ひらがなのあのような1つの文字を扱う場合はcharを使います。一方で、Helloやこんにちはのように複数の文字をまとめて扱う場合はstringを使います。
この違いを理解しないままコードを書くと、シングルクォーテーションとダブルクォーテーションを間違えたり、charに複数文字を代入しようとしてエラーになったりします。
この記事では、C#の文字と文字列について、charとstringの違い、基本的な使い方、変換方法、文字列操作、日本語や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#では、charとstringの違いをあいまいにすると、すぐにコンパイルエラーが発生します。
たとえば、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
charとstringの最も大きな違いは、扱える文字数です。
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の比較表
| 項目 | char | string |
|---|---|---|
| 扱う内容 | 1文字 | 0文字以上の文字列 |
| 囲み方 | シングルクォーテーション | ダブルクォーテーション |
| 例 | 'A' | "A", "Hello" |
| 型の種類 | 値型 | 参照型 |
| 空の値 | ''は不可 | ""が使える |
| null | 通常は不可、char?なら可 | 可 |
| 主な用途 | 1文字の比較、文字単位の処理 | 名前、文章、メッセージなどの文字列処理 |
5. 文字と文字列の変換方法
5-1. charをstringに変換する方法
charをstringに変換するには、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
逆に、stringをchar配列に変換するには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("同じ文字列です");
}
ただし、aがnullの場合、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';
charとstringは見た目が似ていても別の型です。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("空文字です");
}
ただし、textが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です");
}
10-4. null参照エラーを防ぐ方法
stringはnullになる可能性があります。nullに対してLengthやContainsなどを呼び出すと、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は、textがnullの場合に例外を出さず、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#で文字や文字列を扱うときは、まずcharとstringの違いを理解することが重要です。charは1文字を扱う型で、シングルクォーテーションを使って表します。一方、stringは0文字以上の文字列を扱う型で、ダブルクォーテーションを使って表します。
C#char c = 'A';
string s = "A";
見た目は似ていても、'A'はchar、"A"はstringです。この違いを理解しておくと、C#の文字処理で発生しやすいエラーを避けやすくなります。
また、文字列から1文字を取り出すにはインデックスを使い、charをstringに変換するにはToStringを使います。文字列の検索、置換、分割、連結には、Contains、IndexOf、Replace、Splitなどのメソッドが役立ちます。
日本語は通常のcharやstringで扱えますが、絵文字や一部のUnicode文字では、見た目の1文字とcharの数が一致しない場合があります。文字化けを防ぐには、ファイル入出力や通信時のエンコーディングにも注意しましょう。
C#の文字と文字列は、コンソールアプリ、Webアプリ、業務システム、ゲーム開発など、あらゆる場面で使います。charとstringの基礎をしっかり押さえておくことで、文字列操作をより正確に、効率よく書けるようになります。

