OS:Windows 10 64bit版
コンパイラ:BCC32
コマンドラインコンパイル
putchar()が上手く機能しません。字化けしてしまいます。
putchar()関数について質問します。
Re: putchar()関数について質問します。
Windows 7 Home Premium Service Pack 1 (64ビット)
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
でテストしましたが、字化けは確認できず、正常に「これは、ファイルシステムのテストです。」と出力されました。
本当にputchar()が上手く機能しないのですか?
ソースコードを実行環境と合わない文字コードで保存し、
そのバイト列がそのまま出力されているため、字化けして見えるだけではないですか?
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
でテストしましたが、字化けは確認できず、正常に「これは、ファイルシステムのテストです。」と出力されました。
本当にputchar()が上手く機能しないのですか?
ソースコードを実行環境と合わない文字コードで保存し、
そのバイト列がそのまま出力されているため、字化けして見えるだけではないですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: putchar()関数について質問します。
もしそうなら、main1()関数も、字化けするはずです。main1()の方は正常に作動します。他のプログラムなら
bcc32 や、cl の場合は正常でも、gcc の場合は正常でも、C++ の時、g++の場合のみ、字化けしたり、します。
何か外部からの干渉もあるのでしょうか?ウイルスが潜んでいるのでしょうか?
bcc32 や、cl の場合は正常でも、gcc の場合は正常でも、C++ の時、g++の場合のみ、字化けしたり、します。
何か外部からの干渉もあるのでしょうか?ウイルスが潜んでいるのでしょうか?
Re: putchar()関数について質問します。
Windows 10 Home, Visual C++ 2017 でも文字化けしますね。
main の先頭に次のコードを追加してみてください。
文字化けしなくなります。
コマンドプロンプトから実行する場合は、
fflush(stdout); getchar(); はなくてもよいでしょう。
また、_IOLBF(行バッファリング) を _IONBF(バッファリングなし) に
変えると、文字化けします。
Linux ではデフォルトで、
標準出力がファイルの場合は _IOFBF(フルバッファリング)で
標準出力が端末の場合は _IOLBF(行バッファリング)となりますが、
Windows では、
標準出力が端末の場合は _IONBF(バッファリングなし)となるようです。
さらに、Windows 10 のコマンドプロンプトは、単一の出力文字列の
最後の文字が、2バイト文字の先頭バイトで終わっていると
エラーだと解釈して、「・」に変えてしまうようです。
以上は私の妄想であって、そうだという記述は見つけることができませんでした。
putchar に限らず他の出力関数でも文字化けします。 _IONBF にするか、または setvbuf なしにしてみてください。
main の先頭に次のコードを追加してみてください。
文字化けしなくなります。
int main(void)
{
char buf[1024];
setvbuf(stdout, buf, _IOLBF, sizeof buf);
main0();
fflush(stdout);
getchar();
return 0;
}
fflush(stdout); getchar(); はなくてもよいでしょう。
また、_IOLBF(行バッファリング) を _IONBF(バッファリングなし) に
変えると、文字化けします。
Linux ではデフォルトで、
標準出力がファイルの場合は _IOFBF(フルバッファリング)で
標準出力が端末の場合は _IOLBF(行バッファリング)となりますが、
Windows では、
標準出力が端末の場合は _IONBF(バッファリングなし)となるようです。
さらに、Windows 10 のコマンドプロンプトは、単一の出力文字列の
最後の文字が、2バイト文字の先頭バイトで終わっていると
エラーだと解釈して、「・」に変えてしまうようです。
以上は私の妄想であって、そうだという記述は見つけることができませんでした。
putchar に限らず他の出力関数でも文字化けします。 _IONBF にするか、または setvbuf なしにしてみてください。
Re: putchar()関数について質問します。
私の仮説が正しい場合、「main1()関数も、字化けするはず」ではありません。
main1()関数ではプログラムに埋め込んだ文字(列)データは出力せず、入力に基づいたデータを出力します。
そのため、通常はある環境で入力に用いる文字コードと出力に用いる文字コードは同じだと考えられるので、
ソースコードの文字コードによる問題は発生しないと考えられます。
('\n'を表すコードが一般的な10ではない特殊な文字コードなら、問題が発生するかもしれませんが…)
一方、main0()関数では、プログラムに埋め込んだ文字(列)データを出力しています。
したがって、ソースコードの文字コードの影響を受ける可能性があります。
ここはわかりません。
ただし、コンパイラによってはソースコードや出力バイナリに用いる文字コードを設定する機能があるので、
その設定の影響も受ける可能性が考えられます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: putchar()関数について質問します。
修理中だった PC (Windows 10 Home 64bit Version 1809) が返ってきたので、今更ですが実験してみました。
以下のコンパイラーで #1 のプログラムをコンパイル実行しました。
GCC
gcc (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
BCC32
Embarcadero C++ 7.30 for Win32 Copyright (c) 2012-2017 Embarcadero Technologies, Inc.
Embarcadero Technologies Inc. bcc32c version 3.3.1 (36350.30c6854.779bede) (based on LLVM 3.3.1)
VC++ (Visual Studio 2017)
Microsoft(R) C/C++ Optimizing Compiler Version 19.16.27030.1 for x64
VC++ (Visual Studio 2019)
Microsoft(R) C/C++ Optimizing Compiler Version 19.20.27508.1 for x64
いずれのコンパイラーでも文字化けせずに表示できました。
Windows10 の現バージョンでコンソールに不具合があるようなのですがつい最近 1809 にアップデートしたためか、レガシーコンソールにはしていなくとも、当方の環境では正常に表示できました。
参考
Windows10 OctoberUpdate(1809) でのコンソールのバグ
もしコンソールの不具合が原因なら、レガシーコンソールを使用することで解消するかもしれません。
なお、C言語標準ライブラリの影響を排除するために以下のようなプログラムでも検証を行いましたが、文字化けせずに正常に表示できました。
以下のコンパイラーで #1 のプログラムをコンパイル実行しました。
GCC
gcc (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
BCC32
Embarcadero C++ 7.30 for Win32 Copyright (c) 2012-2017 Embarcadero Technologies, Inc.
Embarcadero Technologies Inc. bcc32c version 3.3.1 (36350.30c6854.779bede) (based on LLVM 3.3.1)
VC++ (Visual Studio 2017)
Microsoft(R) C/C++ Optimizing Compiler Version 19.16.27030.1 for x64
VC++ (Visual Studio 2019)
Microsoft(R) C/C++ Optimizing Compiler Version 19.20.27508.1 for x64
いずれのコンパイラーでも文字化けせずに表示できました。
Windows10 の現バージョンでコンソールに不具合があるようなのですがつい最近 1809 にアップデートしたためか、レガシーコンソールにはしていなくとも、当方の環境では正常に表示できました。
参考
Windows10 OctoberUpdate(1809) でのコンソールのバグ
もしコンソールの不具合が原因なら、レガシーコンソールを使用することで解消するかもしれません。
なお、C言語標準ライブラリの影響を排除するために以下のようなプログラムでも検証を行いましたが、文字化けせずに正常に表示できました。
#include <windows.h>
int main(void)
{
char buff[] = { '\x82', '\xa0', '\x82', '\xa2', '\x82', '\xa4', '\r', '\n' };
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD nCharsToWrite = 1;
DWORD nCharsWritten;
for (auto c : buff) {
WriteConsoleA(hConsole, &c, nCharsToWrite, &nCharsWritten, NULL);
Sleep(1000);
}
}
Re: putchar()関数について質問します。
的外れかもしれませんが、
> while (putchar(*sp++))
> ;
while (putchar(*sp))
sp++;
とするか
while (fputc(*sp++, stdout))
;
としても文字化けするか確認してみましょう。
規格上 putchar はマクロが許容されているため、putchar(*sp++) とすべきではありません。
> while (putchar(*sp++))
> ;
while (putchar(*sp))
sp++;
とするか
while (fputc(*sp++, stdout))
;
としても文字化けするか確認してみましょう。
規格上 putchar はマクロが許容されているため、putchar(*sp++) とすべきではありません。