ページ 11

C言語について何故printfで漢字出力できるのに、読み込みはできないのか。

Posted: 2015年6月24日(水) 22:51
by リテラルビギナー
gcc環境でプログラミングしてますが

printf("漢字"); は漢字と端末に出力されますが
逆に
scanfで任意の漢字を読み込むのが出来ないのは何故でしょうか?

printfで"漢字"という字を一旦文字コードに変換して
再度文字コードから対応する"漢"、"字"を見つけて出力してるんですよね?
ということはコンパイラはコードと文字の対応関係を把握してるという事だと思うのですが
何故読み込みができないんですか?

Re: C言語について何故printfで漢字出力できるのに、読み込みはできないのか。

Posted: 2015年6月24日(水) 23:30
by みけCAT
リテラルビギナー さんが書きました:printf("漢字"); は漢字と端末に出力されますが
逆に
scanfで任意の漢字を読み込むのが出来ないのは何故でしょうか?
「scanfで任意の漢字を読み込むのが出来ない」という事実は無いに近似できると思います。
使用している文字コードに無い漢字は読み込めませんが、使用している文字コードにある漢字は全て読み込めるはずだと思います。

コード:

#include <stdio.h>

int readUTF8char(char *out) {
	int n;
	if(scanf("%c",out)!=1)return 0;
	if(((*out)&0x80)==0x00)n=0;
	else if(((*out)&0xe0)==0xc0)n=1;
	else if(((*out)&0xf0)==0xe0)n=2;
	else if(((*out)&0xf8)==0xf0)n=3;
	else if(((*out)&0xfc)==0xf8)n=4;
	else if(((*out)&0xfe)==0xfc)n=5;
	else return 0; /* 不正な開始バイト */
	while(n--) {
		if(scanf("%c",++out)!=1)return 0;
		if(((*out)&0xc0)!=0x80)return 0; /* 不正なデータ */
	}
	*(++out)='\0';
	return 1;
}

int main(void) {
	char buffer[1024];
	char buffer2[1024];

	/* 順番を入れ替えると改行文字を読み込んでしまってうまくいかない */

	/* UTF-8の1文字を読み込む */
	if(!readUTF8char(buffer2))return 1;

	/* 文字列を読み込む */
	if(scanf("%s",buffer)!=1)return 1;

	printf("%s\n%s\n",buffer,buffer2);
	return 0;
}
https://ideone.com/HUxVzR
リテラルビギナー さんが書きました:printfで"漢字"という字を一旦文字コードに変換して
再度文字コードから対応する"漢"、"字"を見つけて出力してるんですよね?
ということはコンパイラはコードと文字の対応関係を把握してるという事だと思うのですが
違います。
"漢字"という字を文字コードに変換するのはテキストエディタもしくは端末、IMEなどの仕事のはずです。
文字コードから対応する"漢"、"字"を見つけて出力するのは端末の仕事です。
コンパイラは文字コードは気にせず、書かれているバイト列をそのまま出力ファイルに埋め込むはずです。
オフトピック
ただしgccの-finput-charset=なんとか -fexec-charset=かんとか オプションを使うと、
コンパイラがコードと文字の対応関係を考え、変換を行うはずです。
リテラルビギナー さんが書きました:何故読み込みができないんですか?
予想ですが、%cで1バイト(漢字のデータの一部)のみ読み込む実験を行い、読み込みができないと勘違いしているのではないでしょうか?

Re: C言語について何故printfで漢字出力できるのに、読み込みはできないのか。

Posted: 2015年6月24日(水) 23:32
by namachan10777
私の環境(Linux Mint 17 Cinammon)では

コード:

#include <stdio.h>

int main(){
	char kanji;
	scanf("%[漢]",&kanji);
	printf("%s\n",&kanji);
	return 0;
}
というコードで

コード:

漢字
と入力すると、以下の結果が出力されました。

コード:

Cは詳しくないのでよく分かりませんが、OSも教えて頂けると解答しやすいかと思います。