music1996taro
@music1996taro

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Ruby言語 ファイル 書き出し

# データを書き換えるクラス
class DataReplacement
attr_writer :inputfile, :outputfile

# データを書き換える処理
def replace
output = File.read(@inputfile).split("\n").map do |content|
name, sex_code, tel = content.split(',')
last_name, first_name = name.split
[last_name, first_name, sex(sex_code), separated_tel(tel)].join(',')
end.join("\n")
File.write(@outputfile, output)
end

private

# 性別コードを文字列に変換
def sex(code)
code.to_i == 1 ? '男性' : '女性'
end

# 携帯電話番号をハイフン区切りに変換
def separated_tel(number)
number.match(/(\d{3})(\d{4})(\d{4})/)
"#{$1}-#{$2}-#{$3}"
end
end

replacement = DataReplacement.new
# 入力ファイルの指定
replacement.inputfile = ARGV[0]
# 出力ファイルの指定
replacement.outputfile = ARGV[1]
# データ書き換え
replacement.replace

というソースコードで、コマンドプロンプトで実行した結果、
コマンドには表示されず、excelの拡張子がcsvのファイルに書き出されるみたいなのですが、これも、文字化けしていて、同様の修正を施したものが、

山田,太郎,男性,090-0000-0000
山田,花子,女性,090-1111-1111
鈴木,次郎,男性,090-2222-2222
鈴木,桃子,女性,090-3333-3333
田中,三郎,男性,090-4444-4444
田中,梅子,女性,090-5555-5555
高橋,四郎,男性,090-6666-6666
高橋,桜子,女性,090-7777-7777
佐藤,五郎,男性,090-8888-8888
佐藤,李子,女性,090-9999-9999

がexcelの拡張子がcsvファイルに書き出されるみたいなのですが。教えて頂けると幸いです。

0

4Answer

書き出しの時もやはりエンコーディングを指定した方がいいでしょう。
やりたいことを推測するに、こんな感じでしょうか。
CSVを扱うならCSVライブラリは使ったほうがいいかと。
UTF-8のCSV(BOM有無両方)にも対応させてみました。

require 'nkf'
require 'csv'

# データを書き換えるクラス
class DataReplacement
  attr_writer :input_file, :output_file
  # データを書き換える処理
  def replace
    # input_fileが指定されてなかったらエラー
    raise '入力ファイルが指定されていません。' unless @input_file
    # output_fileが指定されてなかったらエラー
    raise '出力ファイルが指定されていません。' unless @output_file
    # ファイルの先頭部分から文字コードを推測する
    detection = NKF.guess(File.read(@input_file, 2048))
    # 出力先ファイルを開く
    File.open(@output_file, 'w') do |out_file|
      # 出力先ファイルのエンコーディングを指定する
      out_file.set_encoding(detection, Encoding::UTF_8)
      # エンコーディングがUTF-8の場合はbomを最初に書き出す
      out_file.write("\uFEFF") if detection == Encoding::UTF_8
      # 入力ファイルを開く
      CSV.foreach(@input_file, encoding: csv_encoding(detection)) do |row|
        # 変換した結果を行毎に出力する
        out_file.puts(replace_row(row))
      end
    end
  end

  private

  # CSV読み込み時のエンコーディングを作成する
  def csv_encoding(detection)
    # Shift_JISだと判定された場合はCSV用に使われるCP932で読み込む
    return 'CP932:UTF-8' if detection == NKF::SJIS
    # UTF-8の場合bomがついている場合があるので'BOM|'をつけて読み込む
    return 'BOM|UTF-8:UTF-8' if detection == NKF::UTF8
    # どちらでもない場合はとりあえず推測した文字コードで読み込む
    return "#{detection.to_s}:UTF-8"
  end

  # 行単位の変換処理
  def replace_row(row)
    out_row = row[0].split
    out_row << sex(row[1])
    out_row << separated_tel(row[2])
    out_row.to_csv
  end

  # 性別コードを文字列に変換
  def sex(code)
    code.to_i == 1 ? '男性' : '女性'
  end

  # 携帯電話番号をハイフン区切りに変換
  def separated_tel(number)
    number.match(/(\d{3})(\d{4})(\d{4})/)
    "#{$1}-#{$2}-#{$3}"
  end
end

replacement = DataReplacement.new
replacement.input_file, replacement.output_file = ARGV
replacement.replace
1Like

ExcelでCSVファイルを読み込んだときに文字化けするのは
そのテキストファイルがUTF-8エンコードされているのにBOM(Byte Order Mark)がファイルの先頭に付いていないからだと思います

ファイルを開いたら

"\uFEFF"

を出力してその後にCSVファイルとするデータを書き出します

元のCSVがShiftJISエンコードならBOMではなくShiftJISエンコードで書き込めば読めます

あと困ってるのはわかりますが一度に質問せず1つ1つ解決していってください

1Like

Comments

  1. @music1996taro

    Questioner

    ファイルを開いたら"\uFEFF"をどこにどうやって出力すれば良いのでしょうか?教えて頂けると幸いです。

  2. 質問丸投げではなくご自身でも考えましょう
    挿入しようとしてうまくいかなかったらその状況を書いてもらえれば答えます

    回答者は便利屋ではありませんよ

教えて頂けると幸いです。

状況の説明だけ書かれていて質問がありません。知りたいことは何ですか?

0Like

markdown での コードは

```rb
code..
```

の様に装飾してください。
markdown と競合して見づらいです

0Like

Comments

  1. @music1996taro

    Questioner

    例えば、このコードだとどうやって直せば良いのでしょうか?教えて頂けると幸いです。お手本を見せて欲しいです。

  2. いや、 こっちはその文面の修正権限が無く、 ソースも見れないので ソースとして書いているところに ``` 付けてって言っているのですが……。(詳しい書き方についてはリンクを参照のこと。

  3. 下記の質問 の本文 を こっちの本文に反映した方がいいのではないでしょうか?

Your answer might help someone💌