7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude CodeでShift_JIS環境と格闘した話 - 文字化け地獄からの生還

Last updated at Posted at 2025-12-10

Claude CodeでShift_JIS環境と格闘した話 - 文字化け地獄からの生還

Claude Codeを使って開発していたら、突然ファイルが文字化けして全滅しました。
UTF-8前提のAIツールを、Shift_JIS環境で使う際の落とし穴と解決策を共有します。

事の発端:平和な開発からの突然の悲劇

開発していた環境

  • レガシーなWebアプリケーション(15年以上稼働中)
  • すべてのファイルが Shift_JIS エンコーディング
  • 日本語コメント・日本語変数名が大量に存在
  • 理由:Windows環境で日本語を扱うため、当時はShift_JISが標準だった

やりたかったこと

私:「この関数に日本語コメントを追加して」

期待していた結果

// ユーザーデータを取得する関数
function getUserData(userId) {
    // データベースから取得
    return db.query("SELECT * FROM users WHERE id = ?", userId);
}

実際の結果

// 繝ヲ繝シ繧カ繝シ繝�繝シ繧ソ繧貞叙蠕励☆繧矩未謨ー
function getUserData(userId) {
    // 繝�繝シ繧ソ繝吶�繝シ繧ケ縺九i蜿門セ�
    return db.query("SELECT * FROM users WHERE id = ?", userId);
}

完全に文字化け。 使えないじゃん悲しい...


原因究明:なぜ文字化けしたのか

調査結果

Claude CodeのEditツールはUTF-8前提で動作する

  1. ファイルを読み込む → UTF-8として解釈(実際はShift_JIS)
  2. 日本語文字列を追加 → UTF-8で挿入
  3. ファイルを保存 → UTF-8とShift_JISが混在
  4. 結果:文字化け

簡単に言うと

「Shift_JISで書かれた本に、UTF-8の文字をそのまま貼り付けた」状態。
当然読めなくなります。


第一次対策:手動変換(失敗)

やったこと

# ファイルをUTF-8に変換
iconv -f SHIFT_JIS -t UTF-8 file.js > file_utf8.js

# Claude Codeで編集

# Shift_JISに戻す
iconv -f UTF-8 -t SHIFT_JIS file_utf8.js > file.js

問題点

  • 毎回手動でやるのが面倒
  • 変換忘れが頻発
  • チームメンバーにも同じ手順を強いることになる

結論

手動運用は無理。自動化が必須


第二次対策:Edit禁止・Bashで自動化(成功)

基本方針

Claude CodeのEditツールを使わず、Bashコマンドで編集と変換を一気に実行

新規ファイル作成の場合

# 1コマンドで作成+変換を実行
cat > /path/to/file.js << 'EOF'
// ユーザーデータを取得する関数
function getUserData(userId) {
    return db.query("SELECT * FROM users WHERE id = ?", userId);
}
EOF
iconv -f UTF-8 -t SJIS /path/to/file.js > /tmp/temp.js && mv /tmp/temp.js /path/to/file.js

ポイント:

  • catで一旦UTF-8で作成
  • iconvでShift_JISに変換
  • &&で連結して1コマンド化(確認プロンプトを回避)

既存ファイル編集の場合(方法1:Pythonバイナリモード)

# バイナリモードで読み書きすることで、エンコーディング問題を回避
python3 << 'EOF'
# バイナリモードで読み込み(エンコーディング変換なし)
with open('file.js', 'rb') as f:
    content = f.read()

# バイト列レベルで置換
content = content.replace(
    b"old text",
    "新しい日本語テキスト".encode('shift_jis')
)

# バイナリモードで書き込み(構造完全保持)
with open('file.js', 'wb') as f:
    f.write(content)
EOF

ポイント:

  • rb(read binary)で読み込むことで、エンコーディングを気にしない
  • 日本語部分だけ .encode('shift_jis') でShift_JISバイト列に変換
  • wb(write binary)で書き込み

既存ファイル編集の場合(方法2:sed + iconv)

# ASCIIのみの置換なら安全
sed -i 's/oldText/newText/g' file.js

# 日本語を含む場合は変換が必要
echo "新しい日本語コード" | iconv -f UTF-8 -t SHIFT_JIS >> file.js

第三次対策:CLAUDE.mdで「エンコーディング憲法」を制定

問題

毎回「Shift_JISで保存して!」と指示するのは面倒。

解決策

プロジェクトのルールとして明文化し、Claude Codeに自動で守らせる。

CLAUDE.mdに追加した内容

## エンコーディング(最重要・必須・完全自動化)
**絶対厳守ルール**: ファイルの作成・編集は以下の方法で**完全自動化**すること。

### 🔴 対象ファイル(全てShift_JIS必須):
- `.js` ファイル
- `.html` ファイル
- `.css` ファイル
- その他、日本語を含む全ファイル

### ✅ 新規ファイル作成時
```bash
cat > /path/to/file.js << 'EOF'
[ファイル内容]
EOF
iconv -f UTF-8 -t SJIS /path/to/file.js > /tmp/temp.js && mv /tmp/temp.js /path/to/file.js

✅ 既存ファイル編集時(Pythonバイナリモード推奨)

python3 << 'EOF'
with open('file.js', 'rb') as f:
    content = f.read()
content = content.replace(b"old", "".encode('shift_jis'))
with open('file.js', 'wb') as f:
    f.write(content)
EOF

❌ 絶対禁止

  • EditツールでShift_JISファイルを編集
  • sedで日本語を直接挿入

### 効果
このドキュメントを作成後、Claude Codeは**自動的に正しい方法**でファイルを編集してくれるようになりました。

---

## 検証方法:文字化けしていないか確認

### ファイルのエンコーディング確認
```bash
file file.js

# 正常な場合
# file.js: Non-ISO extended-ASCII text

# 異常な場合(UTF-8混在)
# file.js: UTF-8 Unicode text

文字化けチェック

# Shift_JISとして正しく読めるか確認
iconv -f SHIFT_JIS -t UTF-8 file.js | less

# エラーが出たら文字化けしている

自動修復スクリプト

# 間違ってUTF-8で保存してしまった場合の修復
check_encoding() {
    local file=$1
    if file "$file" | grep -q "UTF-8"; then
        echo "警告: Shift_JISファイルにUTF-8混在検出!"
        # バックアップ作成
        cp "$file" "${file}.bak"
        # 修復
        iconv -f UTF-8 -t SHIFT_JIS "$file" > "${file}.tmp"
        mv "${file}.tmp" "$file"
        echo "自動修復完了"
    fi
}

# 使用例
check_encoding file.js

学んだ教訓

1. AIツールのエンコーディング前提を確認せよ

Claude Codeは素晴らしいツールですが、UTF-8前提で動作します。
Shift_JIS環境で使う場合は、追加の工夫が必要。

2. Editツールは万能ではない

状況によっては、BashコマンドやPythonスクリプトを使う方が安全。

3. プロジェクト固有ルールは必ず文書化

CLAUDE.mdに書いておけば、チーム全員+AI全員が守ってくれる。

4. 自動化できることは自動化

「毎回手動で変換」は必ず破綻する。1コマンド化が重要。

5. バックアップは必須

.bakファイルを作る癖をつけておくと、文字化けしても復旧できる。


他のエンコーディング問題と解決策

問題1:CSVファイルのエンコーディング

Excelで開くCSVは**Shift_JIS(BOM付き)**でないと文字化け。

解決策:

# UTF-8 → Shift_JIS (BOM付き)
iconv -f UTF-8 -t SHIFT_JIS < input.csv > output.csv
# BOM追加
printf '\xEF\xBB\xBF' | cat - output.csv > output_with_bom.csv

問題2:データベースからの日本語取得

データベースがUTF-8、アプリがShift_JISの場合。

解決策:

// 取得時にエンコーディング変換
const iconv = require('iconv-lite');
const data = await db.query("SELECT name FROM users");
const shiftJisData = iconv.encode(data.name, 'shift_jis');

問題3:APIレスポンスのエンコーディング

外部APIがUTF-8、内部処理がShift_JISの場合。

解決策:

const response = await fetch(apiUrl);
const utf8Text = await response.text();
const shiftJisText = iconv.encode(
    iconv.decode(Buffer.from(utf8Text), 'utf-8'),
    'shift_jis'
);

現在の運用

ワークフロー

  1. ファイル作成・編集時

    • Claude Codeに依頼
    • 自動でBashコマンド or Pythonスクリプト実行
    • Shift_JIS変換も自動
  2. 検証

    • fileコマンドでエンコーディング確認
    • 異常があれば自動修復スクリプト実行
  3. コミット前

    • git hookでエンコーディングチェック
    • UTF-8混在があればコミット拒否

結果

文字化け事故はゼロになりました。


まとめ:UTF-8時代にShift_JISと共存する方法

やるべきこと

  1. CLAUDE.mdでルール明文化
  2. Editツール禁止、Bash/Python推奨
  3. 1コマンド化で完全自動化
  4. file コマンドで検証
  5. git hookで防御

やってはいけないこと

  • ❌ EditツールでShift_JISファイルを編集
  • ❌ 手動変換に頼る
  • ❌ エンコーディング検証を怠る

感想

正直、最初の文字化け事件は本当に焦りました。
お友達を失った感覚

でも、この経験のおかげで、

  • エンコーディングの重要性
  • AIツールの限界と対策
  • 自動化の重要性

を深く理解できました。

**「レガシー環境でAIツールを使う」**というのは、
単に「古いコードを書かせる」だけではなく、
環境の特殊性に対応する工夫が必要だと実感しました。

同じようにShift_JIS環境で開発している方、
UTF-8前提のツールを使う際は、ぜひ気をつけてください!

そして、CLAUDE.mdを整備しておくことを強くお勧めします。
一度書いておけば、あとは自動で守ってくれますよ。


参考資料

エンコーディング確認コマンド集

# ファイルのエンコーディング確認
file filename

# 詳細確認
nkf -g filename

# Shift_JIS → UTF-8 変換
iconv -f SHIFT_JIS -t UTF-8 input.txt > output.txt

# UTF-8 → Shift_JIS 変換
iconv -f UTF-8 -t SHIFT_JIS input.txt > output.txt

Python でのエンコーディング処理

# 読み込み時にエンコーディング指定
with open('file.txt', 'r', encoding='shift_jis') as f:
    content = f.read()

# 書き込み時にエンコーディング指定
with open('file.txt', 'w', encoding='shift_jis') as f:
    f.write(content)

# バイナリモード(エンコーディング問題回避)
with open('file.txt', 'rb') as f:
    binary_content = f.read()
# エンコーディング変換
text = binary_content.decode('shift_jis')

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?