Cソースコードで日本語のファイル名称を設定した際、ちょっとはまったことをメモ。
現象:
Linux環境において、Cソースコードで日本語ファイル名称のファイルを生成すると、ターミナル画面以外では正常にファイル名称を表示できない。
Windows(Windows10)エクスプローラの画面(文字化け)
動作確認環境:
OS:Linux(Ubuntu 22.04) / Kernel 5.19
結論から言うと、原因はこの2つでした。
① ファイル名称の文字コード
② マウントオプション
① ファイル名称の文字コードをUTF-8にする
ファイル名称の文字コード変換方法はこちらを参考にしてください:
https://qiita.com/tester09/items/2b28b6b37febf2f57123
もちろん、これはソースコードで日本語ファイル名称を指定している場合のみの処理です。
もしプログラムの起動パラメータとして(ターミナルで)ファイル名称を指定する場合は、文字コードはUTF-8になるのでこの作業は不要です。
ちなみに、Linuxのnkfコマンドで文字コードを調べることができます。
$ nkf -g <ファイル名>
色んなところでターミナルはUTF-8という表記があるので、調べる必要もないですが、念のため調べたら、やはりターミナルの文字コードはUTF-8でした:
蛇足ですが、エディタでソースファイルの文字コードをshift-jisにしてみたところ、コンソール画面でもファイル名称が崩れました。
② 手動でマウントする場合、マウントオプションにUTF8を指定する
使用するファイルシステムにもよるようですが、VFATの場合はマウントオプションにUTF8を付帯する必要があるようです。
このオプションを付帯せずにリムーバブルメディアをマウントして日本語名称のファイルを生成すると、Linux自動マウント時、もしくはWindows使用時に文字化けが起きるようです。
なお、手動でマウントした場合のマウントオプションと、自動でマウントした場合のオプションは以下の通り:
手動時のマウントコマンド:
$ mount /dev/sdb1 /mnt/p1
付帯オプション
rw
relatime
fmask=0022
dmask=0022
codepage=437
iocharset=iso8859-1
shortname=mixed
errors=remount-ro
自動マウント時の付帯オプション
rw
nosuid
nodev
relatime
uid=1000
gid=1000
fmask=0022
dmask=0022
codepage=437
iocharset=iso8859-1
shortname=mixed
showexec
utf8
flush
errors=remount-ro
uhelper=udisks2
mountオプションを調べると、このオプションは「一部ファイルシステムの固有オプション」のため、VFATとして手動でマウントする場合は「utf8」を明示的に指定する必要がある様子。
マウントオプションの内容はこちらで確認してください:
https://linux.die.net/man/8/mount
utf8の説明を抜粋:
utf8:UTF8 is the filesystem safe 8-bit encoding of Unicode that is used by the console. It can be be enabled for the filesystem with this option or disabled with utf8=0, utf8=no or utf8=false. If 'uni_xlate' gets set, UTF8 gets disabled.