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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

6回答

4364閲覧

2バイトのバイナリデータをSJISの対応する文字で出力する方法

taiki_k

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2018/08/22 14:22

C言語で2バイトのバイナリデータ、例えば0x82a0があるとしてこれが「あ」に対応するのですが、
%sや%cの変換指定子ではこのデータを渡しても「あ」にならないのですがどうすればいいでしょうか。

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

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

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

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

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

rubato6809

2018/08/22 22:21

printf("%s", 33440)はなぜだめか? は疑問の核心だと思われるので、質問に追記したら良いと思います。
guest

回答6

0

ベストアンサー

「あ」を出力するパターンをいくつか考えてみました。

c

1#include <stdio.h> 2int main(void){ 3 4 // 通常の定義 5 char a1[] = "あ"; 6 printf("%s\n", a1); // 文字列で出力 7 8 // コードで指定。配列の中身はa1のパターンと同じ。 9 char a2[3] = { 0x82, 0xa0, 0x00 }; 10 printf("%s\n", a2); // 文字列で出力 11 12 // 上記を文字で出力 13 printf("%c%c\n", a2[0], a2[1]); 14 15 // 質問のパターンは文法的にアウト 16 // %sにはアドレスを渡す必要がある。これは値。 17 //printf("%s\n", 0x82a0); 18 19 // %sにはアドレスを渡す必要があるので変数に格納してから出力。 20 // しかしリトルエンディアン環境ではメモリ上では上位バイトと下位バイトが入れ替わっているので化ける 21 // 0xa082を出力しているのと同じこと 22 int a3 = 0x82a0; 23 printf("%.2s\n", (char*)&a3); // %sの場合NULL終端である必要があるので文字数を2文字に限定 24 25 // 上位バイトと下位バイトを取り出して文字で出力すればOK 26 printf("%c%c\n", a3 / 0x100, a3 % 0x100); 27 28 // 文字列として出力するなら一旦変数に入れなおす 29 char a4[3]; 30 a4[0] = a3 / 0x100; 31 a4[1] = a3 % 0x100; 32 a4[2] = 0x00; 33 printf("%s\n", a4); 34} 35 36

投稿2018/08/23 00:24

編集2018/08/23 00:27
ttyp03

総合スコア16998

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

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

rubato6809

2018/08/23 02:59

// %sにはアドレスを渡す必要がある その通りです。上記のコードで %s に対応する a1、a2、 a4 は文字列の先頭アドレスですし、さらに &a3 も文字列の先頭アドレスとして渡しています。 printf() 側の視点に立てば、%s に対応する引数を「文字列の先頭アドレス」として扱う・みなすという事。 // printf("%s\n", 0x82a0); こうしたら 0x82a0 (== 33440) という値は、文字コードではなく、アドレスとして扱われる・みなされるという事。即ち、そこにどんな値・どんな文字列があるかわかりませんが、33440番地にある文字列を表示しようとします。 ここを理解することが重要です。
guest

0

c

1#include <stdio.h> 2#include <stdint.h> 3int main(){ 4 int a = 0x82a0; 5 printf("%c%c\n", (a>>8) & 0xff, a & 0xff); 6 7 int c = 1; 8 if(*(char*)&c) // エンディアンの確認 9 { 10 // ホストはリトルエンディアン 11 int32_t b = 0xa082; 12 printf("%s", (char*)&b); 13 } 14 else 15 { 16 // ホストはビッグエンディアン 17 int32_t b = 0x82a00000; 18 printf("%s", (char*)&b); 19 } 20}

投稿2018/08/23 05:02

asm

総合スコア15147

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

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

0

1バイトずつ%cで出力します。

C

1int a; 2 3a = 0x82a0; 4printf("[%c%c]\n", a>>8, a&0xFF);

ワイド文字処理機能というのもありますが、よく知りません。

リトルエンディアン前提だと、こういうこともできますね。

C

1printf("[%c%c]\n", ((char*)&a)[1], ((char*)&a)[0]);

投稿2018/08/23 00:21

編集2018/08/23 00:31
otn

総合スコア84559

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

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

0

これでいけると思います。

c

1/* char.c */ 2 3#include <stdio.h> 4#include <string.h> 5 6int main(void){ 7 char msg[]={0x82,0xa0,0x00}; 8 printf("%s\n", msg); 9}

私の環境のモジコードがUTF-8で0x82 0xa0 の文字コードがわからなかったので、nkfを間にいれました。
gcc char.c -o char && ./char | nkf -u

投稿2018/08/22 14:49

fu7mu4

総合スコア1088

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

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

0

%sや%cの変換指定子では

とありますが、具体的には、どう記述していますか?
%c については、1文字(1 byte)指定なので、なんとなく予想できますが、 %s については、数字(int)をそのまま、指定したのでしょうか?

手元で、

C

1 char str[10] = "\x82\xa0\n"; 2 printf("%c%c%c", str[0], str[1], str[2]); 3 printf("%s", str); 4

とし、VC++ 2017 でコンパイルしたら、問題なく、"あ" が2行出力されました。
(Windowsの コマンドプロンプトで実行)

指定の仕方じゃないかと思います。

投稿2018/08/22 14:44

編集2018/08/22 14:52
pepperleaf

総合スコア6383

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

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

taiki_k

2018/08/22 15:01

%sにそのままintの整数をわたしていました。printf("%s", 33440)みたいな感じです。 これはなぜだめなんですか?
yumetodo

2018/08/23 11:13

%sはconst char*を要求します
pepperleaf

2018/08/23 12:29

既に他の解凍にありますが、"%s" を指定した場合、引数は、アドレスとみなされます。他の言語はともかく、C の場合、コンパイルレベルでの確認はされず、そのまま、アドレスと解釈されます。(C言語の落とし穴の一つ)
yumetodo

2018/08/23 12:54

可変長引数が安全ではない所以。
guest

0

こんな漢字で、

c

1#include<stdio.h> 2 3int main(void) 4{ 5 char s[10]; 6 int x = 0x82a0; 7 8 s[0] = x / 256; 9 s[1] = x % 256; 10 s[2] = '\0'; 11 printf("%s\n", s); 12}

投稿2018/08/22 14:40

hichon

総合スコア5737

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

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

taiki_k

2018/08/22 15:00

このコードの解説があるとありがたいです。
otn

2018/08/23 00:22

> こんな漢字で、 うまい!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問