質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2136閲覧

C++ std::cout << unsigned char変数 << std::endl;の出力で「\230」と出てくる理由

zuki

総合スコア1

char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2023/01/02 19:55

編集2023/01/02 20:44

前提

Mac, Xcode環境において
C++を使っています。
あるプロトコルにおいて、流れてきているbyte列を扱いたいのですが、基礎的なことがわからず困っています。

xcodeのfile inspectorにはUTF-8が設定されています。

実現したいこと

端的にいうと、std::coutはどのような規則で値を出力しているのかが知りたいです。

unsigned charの型にある1byteの情報が入っています。
それが例えば10進数でいう152、(10011000)の値だとします。

これをstd::coutを使って出力します。

cpp

1unsigned char byte = 152; 2std::cout << "byte: " << byte << std::endl; 3 4std::bitset<8>byte_bit(byte); 5std::cout << "byte_bit : " << byte_bit << std::endl; 6

発生している問題

cpp

1byte : \230 2byte_bit : 10011000

と出力されます。
bit的には確かに152に対応する10011000なのであっているのですが、
なぜbyteそのままだと「\230」と出力されるのでしょう?

分かっていること

127のASCIIが対応している値まではちゃんと出力されます。
126 : ~
127 : DEL(コンソール上は何も見えずに空白のように出力された)
ASCII一覧参考

128~255までは全ては試していませんが以下のようになっています。
10進数 : unsigned char bitset 24bit : coutしたとき
128 : 000000000000000010000000 : \200
129 : 000000000000000010000001 : \201
129 : 000000000000000010000010 : \202
140 : 000000000000000010001100 : \214
152 : 000000000000000010011000 : \230

おそらく、文字コードとかが関わってこの値が表示されているのですが、unicodeやUTF-8を調べてもこの128 ~ 255の値はがどう扱われるのかがよくわかりません。

どういう内部ではフローでこう出力されているのでしょうか?

参考URL
Unicode一覧表
UTF-8コード表

追記 + 疑問

2023/01/03/05:44
コメントをくださった方々、大変ありがとうございます。
hoshi-takanoriさん、ps_aux_grepさんのコメントより、
\230はただ、8進数表記で出力されているだけという単純な話だったということがわかりました。
ただ、なぜ8進数で突然std::coutに出力されているのでしょうか?
ps_aux_grepさんより、Extended Ascii Codeを共有していただいたのですが
これの一覧では、152ÿと表記されています。
これがstd::coutにて出力されていない理由は、utf-8にこの規格が内包されていないからという理解であっているのでしょうか?
私が調べた限り、utf-8は128~256のような値は未定義?になっているからということでしょうか?

補足情報(FW/ツールのバージョンなど)

XCode 12.4
intel mac catalina 10.15.7

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zuki

2023/01/02 20:21

ありがとうございます! ただ、utf-8にない値については、8進数を出力していただけだったんですね。 結論としては、std::coutの仕様について知りたかったということでした。
zuki

2023/01/02 20:29

ありがとうございます! Extended Ascii codeの152 : ÿ がstd::coutにて出力されないのは、 utf-8の規格がそれを内包していない規格という理解であってるのでしょうか? そこらへんの仕組みがよく分かっていません。
PondVillege

2023/01/02 20:33 編集

私も8進で表示される理由がわからないので,とても興味深い内容です. 文字としてはÿであることに対する疑問として,質問に追記すると良いと思います.
zuki

2023/01/02 20:43

追記させていただきました。
dameo

2023/01/02 23:25

Macは持ってないのでよく分からずコメントを控えていましたが、appleのclangだけ特殊なことしてるとは考えにくく、普通にバイナリ出力してるだけではないですか? プログラムも全体を正確に記述し、出力の確認方法も正確に書いた方がいいと思いますよ。 C++もプログラミングも関係なく、ただただ表示上の問題な気がします。
hoshi-takanori

2023/01/03 07:49

ASCII は 0 〜 127 (0x00 〜 0x7f) なので、152 は範囲外です。多くの文字コードが 0 〜 127 を ASCII と共有しつつ、残りの 128 〜 255 (0x80 〜 0xff) に独自の文字を割り当てています。特に、UTF-8 などのマルチバイトコードでは、128 〜 255 は複数バイトからなる文字の一部なので、1 バイトだけ表示しようとしても不正な文字になる可能性があるため、\230 みたいな出力になるんだと思います。 ちなみに、https://ja.wikipedia.org/wiki/UTF-8 によれば、先頭ビットが "10" の場合は2バイト以上の文字の2番目以降のバイトだそうです。
zuki

2023/01/03 20:52

みなさんありがとうございます! そういうことですよね。勉強になりました!
guest

回答2

0

byteというか、char型変数なので、「文字」(1文字)として出力しているだけでしょう。
ファイルにリダイレクトするかパイプでつないで16進表示してみれば、98(16進)と表示されるかと思います。
バックスラッシュ+8進数で表示されたのは、非ASCII文字に対してそういう表示をする端末とかIDEで実行したせいでしょう。

投稿2023/01/03 02:11

otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

std::cout を通じて 1 バイトを出力すれば標準出力に 1 バイトを出力するだけです。 何も加工されません。

標準入出力はある種の窓口であり、その先はプログラムの外の世界です。 標準出力は一般的にプロセス間通信の一種としてデフォルトではターミナルに接続されているのでどのように扱う (表示する) かはターミナルの実装次第です。 もはや std::cout とは関係ないです。

文字に対応づかないビットパターンを (画面に何も反映しないというのもアレなので) 便宜的に適当な表現を割り当てているだけと思われます。

投稿2023/01/03 01:01

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問