質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • Ruby

    8953questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

rubyのFileクラスから指定した文字数まで読み込む方法

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,481

ayu

score 196

こんにちは。
現在、rubyで指定した文字数までを取得したいのですが、うまく取れません。

機能としては、次のことを行おうとしています。
①ファイルから全体の文字数を取得(例えば2200)
②全体の文字数から指定した範囲で切り取る(今回は仮で500)
③②の切り取った文字で、指定した文字(。)等まで削除して整形する(例えば、500文字から一番最後の(。)までを削除)
④③の最後の開始位置から新しく500文字を取得

今、詰まっている場所は次のことです。
②全体の文字数から指定した範囲で切り取る(今回は仮で500)のところで、ファイルクラスから切り取った文字数を入れたが、バイト数になっており、文字数が全然合わない。

汚いソースですが、下記のように記述しております。
file = File.open 'example.txt'#読み込むファイル
result = Hash.new
i = 0
while i < 5 #とりあえずハッシュ形式でデータ取得
  file.each_line do |line|
    result.store(i, line)
  i += 1
  end
end

sum = 0 #文字数の合計数を取得
result.each_value do |value|
  sum += value.length
end

puts "文字の合計数は#{sum}"

sum = 0 #指定した文字数に切り取る
result.each_value do |value|
  sum += value.length
  if sum > 500 
    break
  end
end
p sum
file = File.open 'example.txt'
puts file.read(sum) #ここは表示がバイト数のため、指定した文字数にならない>_<
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

おそらく解決したい問題は、IO#read()の引数で指定するものがバイト数だと言うことですよね。IO#readで長さを指定する場合はバイナリモードになるので、文字の概念はありません。
IO#getcで1文字ずつ読むのは可能なので、それを500回繰り返すということも出来ますが、それだと遅いので、一度ファイル全体を読み込んでしまうのが普通でしょう。

file = File.open 'example.txt'
puts file.read[0, sum]
わかりやすく書くと、
file = File.open 'example.txt'
data = file.read #ファイル全体を読み込み
puts data[0, sum] # dataの先頭sum文字

全体だと、
①ファイルから全体の文字数を取得(例えば2200)
②全体の文字数から指定した範囲で切り取る(今回は仮で500)
③②の切り取った文字で、指定した文字(。)等まで削除して整形する(例えば、500文字から一番最後の(。)までを削除)
④③の最後の開始位置から新しく500文字を取得 
data_rest = IO.read 'example.txt'  #ファイルを全部読み込む
puts "全体文字数は、#{data_rest.size}"

while data_rest
  data = data_rest[0, 500]  #先頭の最大500文字
  data_rest = data_rest[500..-1] #その残り。残りが無ければnilになる
  dataに対して③の処理。dataがちょうど空文字列のケースもあるので注意。
end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/11/17 10:21

    otnさん
    回答ありがとうございます。

    >おそらく解決したい問題は、IO#read()の引数で指定するものがバイト数だと言うことですよね。

    まさしくその通りです。
    表現がわかりづらく、申し訳ございませんでした。
    全体として処理を書いていただき、ありがとうございます。

    IOクラスの概念やできることをまだまだ知らないことが多かったです。

    自分は強引にstrクラスに変更するようにしていました・・・w
    sum = 0 #文字数の合計数を取得
    sentence = ''
    result.each_value do |value|
    sum += value.length
    sentence += value
    end

    otnさんの方がスマートなので、実行してみます。
    ありがとうございます!

    キャンセル

同じタグがついた質問を見る

  • Ruby

    8953questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。