これが怖いの自分だけ?というものありますか?

Cのプログラムで fp = fopen(filename,"rb"); を実行すると必ずエラーになるファイル名があります。

色々調べた結果、エラーになるファイル名にSJISに存在しない文字コードが含まれているらしいことがわかりました。
そのようなファイル名の文字コードをSJISの類似の文字コードに
例えば、⓪ → (0) のようにエクスプローラ上での手作業で変更すれば読めることも確認しています。

これらの作業をするアプリをCで作成しようと思いましたが、エラーになるファイル名の検出まではできますが、
 関数rename(読めないファイル名、読めるファイル名);
でエラーになってしまい、ファイル名変更ができません。読めないファイル名はfopenでエラーになるので、関数renameでもエラーになるのは当然ですが・・・
一方、文字コードをunicode にすれば読めますが、今度はSJISで読めないファイル名の検出ができません。

で質問です
個別の手作業ではなく、一括してこれらの作業ができるコマンドやアプリ、教えてください

質問者からの補足コメント

  • つらい・・・

    いろんなアドバイス感謝です。
    それぞれにお礼をしたいところですが、実働アプリを作成くださったNo5さんをベストアンサーにさせていただきます。
    おひとりしかベストアンサーだせないのが辛いです。

      補足日時:2024/11/05 11:28

A 回答 (5件)

No3です。


下記URLへアップしました。
https://ideone.com/Fu7bKq

Python 3.12.5で動作確認しています。
スクリプトはUTF-8で保存してください。
ファイル名は、rename.pyとします。
pythonにパスが通っているものととします。
コマンドプロンプトで
python rename.py と入力すると以下のメッセージが表示されます。
------------------------------------------
指定されたディレクトリ下のファイルについて再帰的に以下の処理行う
rename.py P1 P2
P1:機能コード
list :SJISに変換できないファイルの一覧を出力する
exec :SJISに変換できないファイルをSJISに変換可能なファイルにリネームする
P2:ディレクトリ名
---------------------------------------

1.機能コード:list
listを指定すると、SJISに変換できないファイルの一覧を表示します。
(ファイル名の変更は行いません)
実行結果の例は、以下のようになります。(実行結果例)
-------------------------------------
python rename.py list data
chcp 65001
rename "D:\goo\python\data\名古屋⓼.py" "名古屋(1).py"
rename "D:\goo\python\data\大阪⓷.py" "大阪(2).py"
rename "D:\goo\python\data\東京⓹.py" "東京(3).py"
rename "D:\goo\python\data\dir2\博多⓹.py" "博多(4).py" 変更後のファイル名が存在します
処理終了 リネーム対象となるファイル件数=4
---------------------------------------------
左側がSJISに変換できないファイル名です。
右側が変換できない文字を(N)に変えた結果です。Nは1~の通番
博多⓹.pyの場合、博多(4).pyが既にD:\goo\python\data\dir2内に存在するので、
「変更後のファイル名が存在します」のメッセージが右側に表示されます。

ここに表示された結果は、同時にカレントディレクトリのlog.txt(UTF-8の文字コード)にも出力されます。
このlog.txtをlog.batに変えることにより、ファイル名を変換するためのバッチファイルが簡単に作れます。
バッチファイルとして、使われることを考慮して、
chcp 65001(コマンドプロンプトの文字コードをUTF8対応にする)
rename
の文字が追加されています。
バッチファイルを作る際は、
①右側のファイル名をほかのファイル名にしたいなら、そのように変更する。
②「変更後のファイル名が存在します」の文字が表示された場合は、そのファイル名は使えないので
  ほかのファイル名にする。又、この「変更後のファイル名が存在します」の文字は削除する。
③最後の行(処理終了 リネーム対象となるファイル件数=・・)は削除する。
上記を行ってください。


2.機能コード:exec
execを指定するとSJISに変換できないファイル名をSJISに変換できるファイル名に変更します。
実行結果は以下のようになります。(実行結果例)
-----------------------------------
python rename.py exec data
D:\goo\python\data\名古屋⓼.py ==> 名古屋(1).py
D:\goo\python\data\大阪⓷.py ==> 大阪(2).py
D:\goo\python\data\東京⓹.py ==> 東京(3).py
処理終了 リネーム件数=3
以下の1件のファイルがリネームできませんでした
D:\goo\python\data\dir2\博多⓹.py ==> 博多(4).py
------------------------------------
左側がリネーム前のファイルで、右側がリネーム後のファイル名です。
3件のファイルがリネームされましたが、博多⓹.pyは、既に博多(4).pyが存在するので
リネームされませんでした。
上記の内容は、log.txtにも出力されます。
    • good
    • 0
この回答へのお礼

ありがとう

お礼日時:2024/11/05 11:22

wcstombsを使って、Unicodeファイル名を渡せば、ShiftJISに変換できないファイル名(文字)は判別できると思います

    • good
    • 0
この回答へのお礼

応答ありがとうございます

wcstombs関数ですね
勉強してみます

お礼日時:2024/11/01 18:40

OSはwindowsでしょうか。


pythonで良ければ、以下のような機能をもつスクリプトを提供可能です。
必要であれば、その旨補足ください。

1.指定されたフォルダ内のすべてのファイルに対して、以下の処理を行う。
2.ファイル名がUTF-8からSJISに変更可能なら処理対象外とする。
3.ファイル名がUTF-8からSJISに変更できない場合、その文字を
(n)に置き換える。(nは1からの連番を割り当てる)
4.ファイル名を上記3で変更したファイル名にリネームする。

フォルダ名がUTF-8からSJISに変換できないケースは考慮しない。
そのようなケースがあっても、フォルダ名のリネームは行わない。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
おっしゃるような仕様のアプリが欲しいです
よろしくお願いします。

お礼日時:2024/11/01 18:23

うーん、使えない文字のファイル名も文字列としては扱えるのですかね。


できるならプログラム内でファイル名変換するのではなく、ファイル名変換のバッチファイルを吐かせるという方法はどうでしょうか。
それもできないようだと明示的に文字コードを変換してSJISとUnicodeを併用するプログラムを書く必要がありますけど。
    • good
    • 0
この回答へのお礼

応答ありがとうございます

バッチファイルはSJISでなくてもいいのでしょうか?
SJISしかダメと思ってました。

確かに、Unicodeで書かれたバッチファイルが許されるなら、のぞみありそうです。

検討したいと思います。

お礼日時:2024/10/31 07:30

文字コードを入れ替えながら作業すればよいのでは?


ロケールを文字コードUTF8にしてディレクトリのファイル名をリストした後、
文字コードSJISに変えて読めないファイル名のエラーを検出、
再び文字コードUTF8でリネームすればいいと思うけど。どうかな?
参考↓
http://www1.kokusaika.jp/advisory/org/ja/c_local …
    • good
    • 0
この回答へのお礼

応答ありがとうござます

なるほど、
 fp = fopen(filename,"rb"); を実行してエラーになるファイル名の検出
する代わりに、
 UTF8で書かれたテキストファイルから、文字コードSJISに変えて読めないファイル名のエラーを検出
するのですね

アイデアありがとうございます

お礼日時:2024/10/31 07:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報

このQ&Aを見た人がよく見るQ&A