rubyのFileクラスから指定した文字数まで読み込む方法
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 2,251
こんにちは。
現在、rubyで指定した文字数までを取得したいのですが、うまく取れません。
機能としては、次のことを行おうとしています。
①ファイルから全体の文字数を取得(例えば2200)
②全体の文字数から指定した範囲で切り取る(今回は仮で500)
③②の切り取った文字で、指定した文字(。)等まで削除して整形する(例えば、500文字から一番最後の(。)までを削除)
④③の最後の開始位置から新しく500文字を取得
今、詰まっている場所は次のことです。
②全体の文字数から指定した範囲で切り取る(今回は仮で500)のところで、ファイルクラスから切り取った文字数を入れたが、バイト数になっており、文字数が全然合わない。
汚いソースですが、下記のように記述しております。
現在、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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
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
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/11/17 10:21
回答ありがとうございます。
>おそらく解決したい問題は、IO#read()の引数で指定するものがバイト数だと言うことですよね。
まさしくその通りです。
表現がわかりづらく、申し訳ございませんでした。
全体として処理を書いていただき、ありがとうございます。
IOクラスの概念やできることをまだまだ知らないことが多かったです。
自分は強引にstrクラスに変更するようにしていました・・・w
sum = 0 #文字数の合計数を取得
sentence = ''
result.each_value do |value|
sum += value.length
sentence += value
end
otnさんの方がスマートなので、実行してみます。
ありがとうございます!