
No.7ベストアンサー
- 回答日時:
ここらへんの話を全部説明しようとすると、エンコーディング(Encoding)、キャラクターセット(Encoded Character Set)、フォント(Font)、グリフ(Glyph)とはなんぞやというところまで言及しないといけなくなって、内容的に一冊の本くらいのボリュームになるため、色々な資料を探して目を通して欲しい。
簡単な解説
エンコーディング:どの文字にどの番号を与えるかを取り決めたもの。UTF-8やEUC-JPなど。
キャラクターセット:どの文字を扱うかを取り決めたもの。JIS X 0213やUNICODE 4.0など。
フォント:字体、書体と訳される。文字の形の内、人間が「あ」なら「あ」と文字を識別するんだけど、とめはねがあったりなかったりするもの。明朝体・ゴシック体やセリフ体・サンセリフ体など。
グリフ:字形。葛飾区の葛の左下がヒだったり人と縦棒と横棒だったり、識別される文字としては同じ葛なんだけど、形が違うもの。例に出した葛は、NECのFA明朝(JIS78版)とMS明朝では、同じコードポイントでFA明朝は人と縦棒と横棒であり、MS明朝ではヒになっている。UNICODEの世界においてもバリエーションセレクターという概念が導入されて、同じコードポイントでグリフが違うものを表現できる仕組みになっている(にも関わらず鴎(かもめ)とメが口3つになったものはグリフが違うだけなのに別のコードポイントが割り当てられているなど対応に全く統一性がないので混乱しちゃう)。
さて、今までで○○は△△だ、いやそうじゃないと色々議論されている中で正確なところをまとめてみたい。質問者が混乱しそうなポイントに絞って説明する。
・UTF-8は1文字が4バイトまでではなく6バイトまでが正しい。
サロゲートペアを32ビットの状態でUTF-8符号化を行った場合に最大で6バイトになる。のだが、Javaには関係ないお話。詳細は後述。
・「Javaの内部文字コードはUTF-16」は半分誤り。
何を以て「内部文字コード」と表現するかにもよるのだが、物理的には変則的なUTF-8で物理メモリ上に格納されているので物理的にはUTF-16ではない。
論理的には、(サロゲートペアやバリエーションセレクターは例外として)Javaにおける1文字とは1つのcharに代入できる値の範囲であり、格納される各文字に割り当てられた値はUTF-16と完全に一致する。
変則的なUTF-8と言ったのは、サロゲートペアはUTF-8では前述の通り32ビットのコードポイントが1バイトから6バイトに符号化されるのだが、Javaでは上位サロゲートと下位サロゲートそれぞれ16ビットを1バイト~3バイトに符号化して格納している。これはサロゲートペアが導入されたJava5(1.5.0)の時点でのお話なので、今(Java1.7や1.8)では事情は違うかもしれない。
・EUC-JPは半角は1バイト、全角は2バイトは誤り。
EUC-JPはキャラクターセットとしてJIS X 0201、JIS X 0208、JIS X 0212の合同集合を扱う事ができるエンコーディング方式なのだが、JIS X 0201のカナ部分は1バイトではなく3バイトで符号化される。つまりEUC-JPでも2バイトを超える文字があるのだ。
ところで、質問にある「C言語であれば全角は2バイト、半角は1バイト」という話があるが、これは日本のプログラマーにとって身近だったMS-DOS(R) 日本語版でMS-CやBorland-C++にて開発する時、あるいはMS-Windows(R) 日本語版でVisual C++で開発する時に、何も特別な事をしないでファイルを読み書きするとShiftJIS(正確にはWindows-31J)で読み書きされていた事に起因すると私は思う。根本的に誤った概念なので忘れた方が良いだろう。
さて、今まではJavaの中で文字列(charやStringクラス)を扱う時のお話をしてきたが、ここでOutputStreamWriterで文字をストリームに書き込む時のお話をしてみよう。
OutputStreamWriterをエンコーディングを指定せずにインスタンス化した時、Javaが勝手にエンコーディングを決めているだけであり、これで例えばそこからFileOutputStreamを経て書き出されたファイルの中身がンバイトだったらかJava内部ではンバイトで格納されているという議論は全く意味をなさない。
この辺はOutputStreamWriterについて詳しく調べてみるといいだろう。
つまり、質問内容に対する回答は、状況によって変わるという訳だ。
Javaが内部で保持しているコードポイントはどの値をどの文字として扱っているかと言えばそれはUTF-16、それを物理的にメモリダンプしたらどうなっているかと言えばそれは変則的なUTF-8チックのエンコーディング方式、ファイルやソケットごしにどうなっているかと言えばそれはエンコードをきちっと指定して使いなさい(それで指定したエンコードでは文字コードの範囲がどうなっているか確認しなさい)という事。
No.6
- 回答日時:
Java にて文字のバイト数は、昔なら2バイト固定だったのですが、最近は「不定」です。
これは Unicode の仕様拡張に由来しているため、Unicode を採用したプログラム言語すべてに共通する特徴になります。
Java 内部処理では char は UTF-16 で扱うので 1単位=2byte
ASCII や JIS カナ(いわゆる半角文字)も1単位
通常の文字は 1文字=1単位=2byte
JIS90範囲内(いわゆる全角文字)ならほぼすべてこれ
一部の文字はサロゲートペアのため 1文字=2単位=4byte
JIS2004の一部が該当
例: U+2000B → 「\uD840\uDC0B」
Unicode正規化で分解されると、結合文字は 1文字=2単位=4byte
Macのファイルシステム関連だとこうなるらしい
例: 「が」→「\u304B\u3099」
アイヌ語表音記号の様にUnicodeに定義が無いなら、正規化されなくとも 1文字=2単位=4byte
JIS2004の一部が該当
例: 「半濁点付き平仮名か」→「\u304B\u309A」
正規化で互換分解までされると、1文字=n単位(n=1..上限未定)
例: 「ローマ数字8」→「\u0076\u0069\u0069\u0069」
上記の特殊ルールを全て加味して文字列のサイズ計算を行うならば、
「バイト数」を知りたいならば String#length に×2
「文字数」を知りたいなら Normalizer してから String#codePointCount
--
内部にシフトJIS/EUCを使っているプログラム言語の場合や、Java の入出力で UTF-8 を使う場合などは、説明が長くなるので割愛させていただきます。
No.5
- 回答日時:
文字コードに絡む「UTF」には複数の意味がありますが, どの意味においても「UTF-8 は 4バイト (『4オクテット』というべき?) まで」のはずです>#2.
ただし「1つのコードポイントがたかだか 4バイト」と言っているにすぎず, #3 に現れる結合文字や異体字セレクタなんかを使いだすと「1文字」のバイト数はもっと増やすことができます (異体字セレクタは 1つしかつけられないが, 理論上結合文字はいくつでもつなげられるので).
No.4
- 回答日時:
Javaに関してはこの辺を読まれるとよいかもです。
http://docs.oracle.com/javase/jp/6/api/java/lang …
また#3の方が既におっしゃっていますが全角半角というのはフォントの話であって、1文字が何バイトなのかとは関係ありません。
No.3
- 回答日時:
JavaやC#(というか.NET Framework)は文字列型の内部コードがUTF-16なので,日本語というか,全ての文字の処理単位が16ビットです。
サロゲートや結合文字,異体字セレクタなどがあるので,1文字が16ビットというわけではありませんが。
例えば,
No.2
- 回答日時:
どんなデータ形で記憶するのか、どの文字コード系を採用したかによります。
Stringやchar[]では、 1文字は16bitです。
String.GetByte()等でbyte[]に記憶する場合は、その文字コード次第です。
SHift_JIS,EUC-JPでは、いわゆる「全角文字」は2バイトです。
UTF-8は1~6バイトです。日本語で使われる文字は、大体3バイトです。
C言語でも事情は同じようなものです。
「全角は2バイト、半角は1バイト」というのは、UTF-8が普及するまではShift_JISやEUC-JPが一般的だったため、そうだと決めつけてしまっているだけです。(特に古い入門書等)

No.1
- 回答日時:
Javaはunicodeを扱うので2バイトです。
2バイトは2の16乗の数が扱えるので、65536個の文字種が理論上表現できます。 基本的に世界中の文字が含まれますが、日本語の漢字と中国語の漢字の字体がまったく同じ場合は、両者は共用されます。
国際規格なので、全ての日本語漢字が含まれているわけではないです。 難読字など存在しないものは、外字で表現するしか方法がないはずです。 外字とはUnicodeの空きエリアを使って、独自に文字をデザインしそれと文字コードが対応するようにしたものです。 当然、フォントデザインがないコンピュータでは、互換性はありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 【C言語】全角文字の配列を、全角のまま1文字ずつ出力する方法 4 2023/05/09 15:08
- C言語・C++・C# 至急お願いします。C言語で.imgのファイルを読み込んで1バイトづつ出力するプログラムを作りたいので 3 2023/01/16 22:49
- Android(アンドロイド) 海外のAndroid 端末の場合、日本語全角は、どう表示されるのでしょうか? 1 2022/10/02 21:16
- Excel(エクセル) capeofdragonと申します Excel2016を使っておりまして 半角又は全角の任意文字列が 2 2022/10/31 13:51
- 英語 アルファベット順の4文字以上の英単語 10 2022/07/30 22:42
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- C言語・C++・C# VisualStudioのソースコードで漢字を使いたい 4 2022/05/21 10:16
- Word(ワード) Windows11キーボードの調子が悪いので治し方を教えてください。 【症状】 1つ目 キーボードの 5 2022/07/03 14:51
- その他(プログラミング・Web制作) 2つのテキストファイルを比べて文字列を特定する方法を教えて下さい 5 2022/05/01 15:22
- UNIX・Linux Postfixでドコモメールに送信すると届くまで10分ぐらいかかる 6 2023/03/05 13:56
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
UTF-8で5~6バイトになる文字コ...
-
10Mバイトて文字数に すると何...
-
COBOLのCOMP形式について
-
char str[256]の256の意味は?
-
バイト列とバイナリ列の違いが...
-
エクセルシート名の制限を変更...
-
ビットスワップとバイトスワッ...
-
Javaで日本語1文字のバイト数
-
windowsのファイルパス最大文字数
-
memcmp バイナリデータの比較方法
-
【VB2005】テキストボックス内...
-
日付時刻を4バイトに
-
C++ Builderで文字列をバイトに...
-
ワイド文字のバイト数が取得で...
-
3バイト文字(UTF-8)をprintfで...
-
Console.writeLineで文字化け
-
VBAでShift-JISのURLエンコード
-
機種依存文字をチェックしたい。
-
:(コロン)のKeyCode
-
GetWindowTextでアドレスバーか...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
UTF-8で5~6バイトになる文字コ...
-
10Mバイトて文字数に すると何...
-
COBOLのCOMP形式について
-
エクセルシート名の制限を変更...
-
char str[256]の256の意味は?
-
バイト列とバイナリ列の違いが...
-
ピクセル,dpiから容量(バイト...
-
C++ Builderで文字列をバイトに...
-
Javaで日本語1文字のバイト数
-
ビットスワップとバイトスワッ...
-
SQLで1バイト、2バイト混在...
-
バイナリとBCDコード
-
URLは最高何文字まで可能なので...
-
機種依存文字をチェックしたい。
-
VBAでShift-JISのURLエンコード
-
COBOL PICTUREで X,S,Vの意味
-
memcmp バイナリデータの比較方法
-
pythonでバイナリデータを配列...
-
64bit対応
-
3バイト文字(UTF-8)をprintfで...
おすすめ情報