• ベストアンサー

rubyで標準入力とファイルからのgets

ActiveScriptRuby v1.8.5でやっています。 実行時にコマンドラインでファイル名を与えてファイルの内容を取得した後、氷人出力からも入力をとろうとしています。しかしファイルの内容を読み出したあとのgetsがnilを返すだけで標準入力から入力をとれません。以下のようなコードでやっています。 ##stdin.rb while line = gets do print line break if line.chomp.empty? end puts' - ' print gets #ここで標準入力から文字をとりたい 実行時は ruby stdin.rb moji.txt という感じで読ませたいファイル名を渡しています。 マニュアルには 最後まで ARGF を読み込んだ後、再度 ARGF から内容を読むと (ARGV が空なので)標準入力からの読み込みとなります。 とありますが、どこがおかしいのかさっぱりわかりません。 アドバイスなどよろしくお願いします

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10261)
回答No.1

おかしいですね。 私の環境(Win32およびLinux)でもマニュアルのその部分のサンプルをファイル名だけ変えて実行してもマニュアルどおりの動きはしないです。 仕様が変わってマニュアルに反映されて無いのか、バグなのか不明ですが、とりあえずは、STDIN.gets とすれば標準入力から読むことは可能です。 あるいは、ループの後で if ARGF.closed? ARGV.relpace ["-"] end と、ARGV/ARGFを明示的に切り替えるか。

matico
質問者

お礼

ありがとうございます。 STDIN getsで目的は果たせそうです。 仕様変更は気づかなかったのでたすかりました

その他の回答 (2)

  • anekos
  • ベストアンサー率57% (4/7)
回答No.3

気になったので調べてみたら仕様変更されているのが見つかりました。(参考URL) 回答にはなりませんが、参考までに。

参考URL:
http://www.ruby-lang.org/ja/man/?cmd=view;name=ruby+1.8.2+feature#ARGF.20.5bchange.5d
matico
質問者

補足

参考URLありがとうございます

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

#1の方の推測の通り、仕様変更があってドキュメントの訂正が間に合っていない(or 忘れられている)か、 ドキュメントがそもそも間違っているかのいずれかだと思われます。 というのも、スクリプトの puts' - ' print gets #ここで標準入力から文字をとりたい ↑この部分で p ARGF.closed? としてステータスをみると、ストリームとしては閉じてしまっています (つまりそこから入力を取ろうとしても無駄)。 また、Cによるソースを見てもそういった動作を意図しているように 読めます(斜め読みなのであまり自信はありませんが)。 ARGF経由で与えられたファイルからすべて読み取った後に 「標準入力」から読み取りを行いたいのなら、陽に STDIN.gets とオブジェクトを指定すべきだろうと思います。

matico
質問者

お礼

どうもありがとうございました。

関連するQ&A

  • Ruby初心者です。

    以下の練習問題をやっているのですが、どうもうまくいきません。 (1)担当名が"end"になる迄、担当名と売上を入力する。 (2)売上合計を求める。 (3)各担当の売上が売上合計の何%になるかの比率の計算を行う。 (4)担当名、売上、比率を表示する。 どこがいけないのがご教授頂けますでしょうか。 よろしくお願い致します。 *********************************** #! ruby -E Windows-31J:utf-8 # coding: utf-8 kensu = 0 uriage = 0 goukei = 0 uriage_t = [20] tanto = [10] tanto = [20][10] puts("担当名がendで終了") print(kensu = kensu + 1, "人目の担当名は") tanto = $stdin.gets.chomp! tanto.gsub!("\n", "") print("売上") uriage = $stdin.gets.chomp!.to_i while tanto != "end" kensu = kensu goukei = goukei + uriage uriage_t = uriage tanto_t = tanto print(kensu = kensu + 1, "人目の担当名は") tanto = $stdin.gets.chomp! tanto.gsub!("\n", "") if tanto != "end" print("売上") uriage = $stdin.gets.chomp!.to_i end end kensu = kensu + 1 goukei = goukei + uriage uriage_t = uriage tanto_t = tanto, "合計" puts "________________________________________" puts "  担当      売上  比率  " puts "________________________________________" for i in kensu kensu += i ritu = uriage * 100 / goukei puts "担当名は#{tanto} 売上は#{uriage_t}円 比率は#{ritu}%" end

  • Ruby 暗号化したファイルの復号について

    Rubyでファイルを暗号化し、それを復号したいのですがうまくいかないため、 質問させていただきます。 Ruby 1.9.3を使用しています。 ・ファイルの暗号化 encrypt.rb ------------------------------------------------- # encoding: cp932 require 'openssl' def encrypt(file, pass)   enc = OpenSSL::Cipher::AES256.new('CBC')   enc.encrypt   enc.pkcs5_keyivgen(pass)   File.open(file, 'rb') do |fin|     File.open("#{file}.sec", 'wb') do |fout|       while buff = fin.read(8000)         fout.write(enc.update(buff))       end       fout.write(enc.final)     end   end   enc.reset end if $*.length > 0   print 'password: '   pass = $stdin.gets.chomp   $*.each do |arg|     begin       encrypt(arg, pass)       puts "#{arg}を暗号化したファイル#{arg}.secを作りました。"     rescue       puts "#{arg}の暗号化に失敗しました。"     end   end   0.upto(pass.length - 1) do |i|     pass[i] = '\xff'   end end ------------------------------------------------- ・ファイルの復号 decrypt.rb ------------------------------------------------- # encoding: cp932 def decrypt(file, pass)   dec = OpenSSL::Cipher::AES256.new('CBC')   dec.decrypt   dec.pkcs5_keyivgen(pass)   File.open(file, 'rb') do |fin|     File.open("#{file}.plain", 'wb') do |fout|       while buff = fin.read(512)         fout.write(dec.update(buff))       end       fout.write(dec.final)     end   end   dec.reset end if $*.length > 0   print 'password: '   pass = $stdin.gets.chomp   $*.each do |arg|     begin       decrypt(arg, pass)       puts "#{arg}を復号したファイル#{arg}.plainを作りました。"     rescue       puts "#{arg}の復号に失敗しました。"     end   end   0.upto(pass.length - 1) do |i|     pass[i] = '\xff'   end end ------------------------------------------------- コマンドプロンプトでencrypt.rb自身を暗号化し、encrypt.rb.secの作成はできるのですが、 decrypt.rbを実行してパスワードを入力しても復号ができません。 どのようにすれば復号できるのか教えていただけますでしょうか。

    • ベストアンサー
    • Ruby
  • なぜRuby1.9が日本語処理できない問題

    次の簡単なRubyプログラム(test.rb)ですが、 #!/usr/bin/env ruby # -*- coding: utf-8 -*- while gets $_.chomp! tmp = $_.split(/ /) s0 = tmp[0] s1 = tmp[1] s2 = tmp[2] puts "line #{s0}\t#{s1}\t#{s2}" end 入力テキストファイル(hello.txt)は次の2行です。 1 hello, everybody! 2 皆さん、 こんにちは。 test.rb hello.txt を実行すると、Ruby 1.8.7 は問題なく正常ですが。Ruby 1.9.3は次のエラーになりました。 line 1 hello, everybody! k1.rb:7:in `split': invalid byte sequence in US-ASCII (ArgumentError) from k1.rb:7:in `<main>' 何故でしょうか。詳しい方に教えて頂けるでしょうか。 どうぞ宜しくお願いします。

    • ベストアンサー
    • Ruby
  • Rubyのgets関数について

    以下のプログラムを実行して、コマンドプロンプトからsと入力してEnterを押すと、differentと表示されます。sameと表示されることを期待しています。何が原因なのでしょうか?環境はWindows2000です。よろしくお願いします。 i = gets t = "s" if i == t print "same" else print "different" end

  • ruby初心者です

    RDEを使っています。 input_value = gets puts input_value p input_value    を書くと、上に書いたprint文などより先に左下のコンソールに 先に入力するようになります。 コマンドで実行するとうまくいくのですが。 何か設定が間違っているのでしょうか? 教えていただければたすかります。

    • ベストアンサー
    • Ruby
  • 【ruby】特異クラスを使って,File.statをカスタムしたい

    File.statに、nameというメソッドを追加したいです。 st=File.stat('hoge.txt') puts st.name #=> hoge.txt 上記のように使いたいのです。 そこで、以下の様に書いてみました。(行頭のスペースは全角です) class File  class << self   def stat(file)    st=File::Stat.new(file)    class << st     def name      @file     end    end    st   end end end st=File.stat('./hoge.txt') puts st.name #=> nil 上記実行結果はnilが出力され、期待した結果は得られませんでした。 上記の様に書いた理由を以下に記します。 クラスメソッドstatは、file.rbのclass Fileの中に定義されていて、 stat.rbのFile::Stat.new(file)を戻り値としていました。 stat.rbのclass File::Statのinitializeでは、 def initialize(file)  @file = file  (略) end となっていたので、上記の様に書いてみたのですが、何が悪いのでしょうか? ご指導のほど、宜しくお願いいたします。

    • ベストアンサー
    • Ruby
  • Rubyでの比較 (Float)

    Ruby初心者です。 簡単な比較を行いたいんですが、エラーが出てしまいます。 ファイルに ex. ruby_test.rb 0 12.3243 32 112.233 0.33123 とあり、このファイルを読み込んで比較しようとしています。 以下のコードで比較しようとしました。 ----------------------------------------------------------- fp = open("c:/ruby_test.txt") aaa = Array.new while line2 = fp.gets line2.chomp! bbb = line2.split(/\t/) aaa << bbb[1] if ( bbb[2] < 1.301029996 ) then       ※11行目 print "aaa\n" elsif ( bbb[2] < 8.164943898 ) then print "bbb\n" elsif ( bbb[2] >= 8.164943898 ) then print "ccc\n" end end fp.close -------------------------------------------- 実行すると ( ※ **** はファイル名 ) C:/ruby/*******.rb:11:in'<': comparison of String with Float failed (Argument Error) というエラーが出ます。 比較する  bbb[2] < 1.301029996  を bbb[2] < "1.301029996" すれば 動きますが、これでは文字列としての比較になってしまいますよね?? Floatは数字として比較するにはどうしたらよいのでしょうか? どなたか宜しくお願いします。

  • Rubyのpopen3について

    はじめまして Rubyをはじめて1か月の初心者です。 popen3を使用するにあたって大変困っております。 popen3で外部コマンドを実行して、実行結果の標準出力をファイルとして格納しようと思っています。 外部コマンドの内容は、SSH接続でサーバへログインし、そこにあるシェルスクリプトを実行させるもので、 呼び出すシェルスクリプトに対して、Rubyから標準入力を渡し、シェルスクリプトが標準入力を受け取り、 それをもとに呼び出したシェルスクリプトがさらに別のシェルスクリプトを呼び出し、実行結果を標準出力としてRubyで受け取ってファイルに格納したいと思っています。 ソースとしては、以下のようにしてますが、標準入力を引き渡す方法が分かりません。 その為、標準入力を引き渡す部分は記述していません。 Open3.popen3('ssh localhost sh test.sh ') do |stdin, stdout, stderr|   begin    loop do     IO.select([stdout,stderr]).flatten.compact.each { |io|      if stdout != "" then       stdout_lines = stdout        puts("stdout_lines = " + stdout_lines)      end      stderr_lines = stderr if stderr != ""      puts("stderr_lines = " + stderr_lines)     }     break if $stdout.classed? && $stderr.closed?   end   rescue EOFError   end end JRubyの1.6.8なので、Rubyのバージョンは1.8.7相当です。 なにぶん初心者の為、なにをどうすれば良いか分からない状態です。 まず、実現が可能かを知りたいです。 実現可能であれば、標準入力を引き渡す方法を教えていただきたく。 よろしくお願いします。

  • [Ruby] irbにおける文字化け

    Rubyを勉強を始めようと思いまして、Active Script Ruby1.8.22をインストールし、irb(Interactive RuBy)を使って簡単な機能の勉強をしていました。 その際、ある特定の場合、日本語が文字化けしてしまう。という分からないことが出てきましたので質問させて頂きます。 一つ目は、 printやputsなどで日本語を表示させようとする場合、 print("") print("あいうえお") のように、print("") と入力後、カーソルを移動させ "" の中に あいうえお を入れた後エンターすると以下のように print("あいうえお")と表示されるところが文字化けしてしまうということです。しかし、それを実行すると、しっかりと あいうえお と表示されます。 irb(main):031:0> print(" 「 、 ヲ ィ") あいうえお=> nil これを文字順通りに、 print(" print("あいうえお print("あいうえお") のように、print("  の後に、あいうえお を入力。その後括弧閉じすると以下のようにしっかりと、print("あいうえお")と表示されます。 irb(main):032:0> print("あいうえお") あいうえお=> nil どちらの実行結果も変わらず、しっかりと あいうえお と表示されるのですが、やはり命令入力の段階での文字化けが気になります。 二つ目は、 配列の文字化けです。 waza = ["殴る", "蹴る", "強く殴る", "強く蹴る"]といれてエンターすると、以下のように配列の中の日本語が文字化けします。 (また、これも当然一つ目のprintやputsのように、 waza = ["殴る", "蹴る", "強く殴る", "強く蹴る"] を書く際に先に waza = ["", "", "", ""] と書いた後、カーソル移動で日本語入力すると、命令の部分も文字化けします。以下に載せているのは、命令部分が文字化けしないように左から順に書いていったものです。) irb(main):022:0* waza = ["殴る", "蹴る", "強く殴る", "強く蹴る"] => ["\211\243\202\351", "\217R\202\351", "\213\255\202\255\211\243\202\351", "\ 13\255\202\255\217R\202\351"] irb(main):023:0> 5.times do irb(main):024:1* waza.each do |w| irb(main):025:2* print(w) irb(main):026:2> print(" ") irb(main):027:2> end irb(main):028:1> print("\n") irb(main):029:1> end 殴る 蹴る 強く殴る 強く蹴る 殴る 蹴る 強く殴る 強く蹴る 殴る 蹴る 強く殴る 強く蹴る 殴る 蹴る 強く殴る 強く蹴る 殴る 蹴る 強く殴る 強く蹴る => 5 これも、printやputsと同じように結果はしっかりと文字化けせず表示されるのです。 使用OSはWindows XP Home Edition version2002 Service Pack 2です。 あまりよく分かっていないため、分かりにくく、ややこしい文ですが、回答をお待ちしています。よろしくお願いします。 状況等で詳しく知りたいところや何か分からない所がありましたら質問していただければ幸いです。分かる範囲で答えたいと思います。 参考になるかは分かりませんが、他の文字での文字化け例を下記します。 [1]左から順に入力したputs("こんにちは") irb(main):035:0> puts("こんにちは") こんにちは => nil [2]先にputs("")を入力したputs("こんにちは") irb(main):036:0> puts(" ア ノ ソ ヘ") こんにちは => nil [3]waza =["", "", "", ""]を先に入力後カーソル移動で日本語入力したwaza = ["殴る", "蹴る", "強く殴る", "強く蹴る"] irb(main):037:0> waza =[" 」 ・, " R ・, " ュ ュ 」 ・, " ュ ュ R ・] => ["\211\243\202\351", "\217R\202\351", "\213\255\202\255\211\243\202\351", "\2 13\255\202\255\217R\202\351"] irb(main):038:0> waza[0] => "\211\243\202\351" irb(main):039:0> waza[1] => "\217R\202\351" [4]wazaの要素の出力 irb(main):040:0> waza.each do |w| irb(main):041:1* print(w) irb(main):042:1> end 殴る蹴る強く殴る強く蹴る=> ["\211\243\202\351", "\217R\202\351", "\213\255\202\2 55\211\243\202\351", "\213\255\202\255\217R\202\351"]

  • Perlのプログラミングについて

    Perlのプログラミングでつまづきました。 # ファイルから指定文字列を含む行を収集する # 入力ファイルのオープンと読み込み print( "入力ファイル名?" ); $n = <STDIN>; chomp( $n ); open( FIN, "<$n" ) or die "入力ファイルオープンエラー: $!\n"; $n = @a = <FIN>; close( FIN ); print( "$n 行読み込みました\n" ); # 行の収集 print( "検索文字列?" ); $x = <STDIN>; chomp( $x ); $ptn = $x; #指定の文字列 $x = @b = grep( /$ptn/, @a ); print( "$x 行見つかりました\n" ); # 出力ファイルのオープンと書き出し print( "出力ファイル名?" ); $y = <STDIN>; chomp( $y ); open( FOUT, ">$y" ) or die "出力ファイルオープンエラー: $!\n"; print FOUT ( $ptn, "\n" ); print FOUT ( $x, "\n" ); print FOUT ( @b ); close( FOUT ); というプログラムで実行すると C:\My Perl\pl>perl プログラムの実行.pl 入力ファイル名?sample1.txt 168 行読み込みました 検索文字列?k 45 行見つかりました 出力ファイル名?out3-24.txt 続行するには何かキーを押してください . . . となり出力ファイルの中身が表示されません。 どこを間違えているのかご指摘いただけないでしょうか?

専門家に質問してみよう