• 締切済み

Ruby 1.9.3でShift-JIS文字列を

よろしくお願いします。 Rubyでスマフォ(SH-02D)の電話帳のQUOTED-PRINTABLEの文字列を WindowsのShift-JIS文字列に変換してファイルに出力したいのですが putsだと日本語文字列に見えるのですが、printだと[]で囲まれた16進数の (一部は^のように表示されますが)列になってしまいます。 ネットで検索してもprintはそのまま、putsは強制改行があるという 違いしかないように思えるのですがどうすればputsと同じ出力を 強制改行無しに出力できるのでしょうか。 RubyはWindows 7 Professional x64でeclipse INDIGOにAptana Studioを 入れて入力&実行しています。 (プレアデスも入ってます。ソースのエンコードはS-JISです。) sub_column = column[i].split("/;/") quoted_string = sub_column[j].unpack("M") puts quoted_string print quoted_string ---- (抜粋) でputsとprintで見え方が違うのです。

  • Ruby
  • 回答数2
  • ありがとう数4

みんなの回答

  • ki073
  • ベストアンサー率77% (491/634)
回答No.2

普段は1.8.7を使っていてそろそろ1.9へ移行しなければということで、まだ理解できていないところもありますが、 quoted_string.force_encoding("Shift_JIS") でundefined methodになるのは、マニュアルによると.unpack("M")の結果はArrayになります。Stringにするには quoted_string.to_s.force_encoding("Shift_JIS") でどうなりますでしょうか? Array出力しようとしたら、当然to_sを実行後出力されるが、微妙な差がprintとputsにはあるのでしょうか。 macrubyではなく1.9.3で実行してみたら p Encoding.default_internal #-> nil p Encoding.default_external #-> #<Encoding:UTF-8> となりました。nilでも良いみたいですね。 StringIOを使う方法ですが require "stringio" str="" StringIO.open(){|io| io.puts "あいうえお" io.pos=io.pos-1 io.puts "あいうえお" io.pos=io.pos-1 str=io.string } print str こんな感じです。上の例はOSXですので改行コードがLF一文字です。Windowsは-2しないといけないかも知れません。

sakana526
質問者

お礼

どうもありがとうございます。 今、直そうとしていたらどこか(eclipse or Aptanaの)設定を変えてしまったのか、 スクリプトの編集ミスか単語の色分けなどが変わってしまって混乱しています。 ちょっとまだ未確認なのですが、 <書き込みファイルオブジェクト>.puts( hoge )で単純な文字列は強制改行されますが Array(?)データは改行されないように見えたかもしれないです。 unpackした漢字文字列(S-JIS)の直後が改行されていないようにちらっと見えたので どちらにせよ確認もすぐに出来ないのですみません。 バージョン管理を自動でしててくれてるかもしれませんが、 eclipseの操作自体まだ慣れていない状態です。

sakana526
質問者

補足

今日eclipseを立ち上げたらエディターの単語色分けは戻ってました。 御二方のアドバイス通りにposを-2する事で対処することにしました。 昨日の時点ではRubyは1.9.3ではなく1.9.1でした。 インストール先を間違っていたので環境変数のPATHがVer. 1.9.1を指していました。 1.9では require "stringio" は不要なようです。 今度は逆変換のスクリプトを作るつもりです。 単にunpack("M")をpack("M")にしただけでは駄目なようです。

  • ki073
  • ベストアンサー率77% (491/634)
回答No.1

エンコーディングは正しく設定されているでしょうか? p Encoding.default_internal で確認できます。 こちらはmacruby0.9を使っていますが、書き方が悪いのかもしれませんが magic commentが無視されるようで、何を指定してもUTF-8になってしまいます。 (UTF-8で実害はないです) 念のため、 quoted_string.force_encoding("Shift_JIS") としてみてはいかがでしょうか。 あとは、 print quoted_string.to_s や print "#{quoted_string}" にしてみるとか、 どうしようもなければStringIOにputsで出力してposを改行コード分もどすとか。

sakana526
質問者

お礼

(ごめんなさい。ここに上のような事を書くべきだったのでしょうか。) どうもありがとうございました。

sakana526
質問者

補足

ありがとうございます。 p Encoding.default_internal の結果はnilと表示されました。 ソース先頭にマジックコメントで# encoding:Windows-31Jと設定しているのですが。 quoted_string.force_encoding("Shift_JIS") はundefined methodになりました。 後の二つでもどうしても16進数(一部記号)の文字列になったままです。 posを戻すか手作業で出力ファイルから改行を取り除くしかないようですね。 これはprintの仕様なのでしょうか。 それともどこかに報告した方が良いような不具合なのでしょうか。

関連するQ&A

  • 【Ruby】shift-jisのページの置換

    content="text/html; charset=shift-jis"のページを読み込んで、文字列の置換がしたいです。 #!/opt/local/bin/ruby require 'uri' require 'open-uri' url='http://hoge.hoge' open(url,'r:shift_jis'){|io| content = io.read content.gsub!(/ほげ/,'ホゲホゲ) print content } 上記の様に書いてみました。ソースコード自体はUTF-8で記述しました。 実行すると、 `gsub!': incompatible encoding regexp match (UTF-8 regexp with Shift_JIS string) (Encoding::CompatibilityError) となってしまいます。 どうしたらよいのでしょうか? rubyのバージョンは ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-darwin12] です。 以上、よろしくご指導のほど、お願い申し上げます。

    • ベストアンサー
    • Ruby
  • Ruby1.9での文字列操作について。

    Ruby1.9での文字列操作について。 今までRuby1.8を使用していましたが、Ruby1.9に変えてから、次の4種類の問題が出てきました。 (※Ruby1.9に変えてから、#encoding: shift_jisを定義しております) どれか1種類でも結構ですので、Ruby1.9での対策、代替の処理について教えてください。 <問題1> ■文字列を指定のバイト位置まで削除する □現在(Ruby1.8)のコード moji = "1あアあアイ234565789" moji[4,14] = "" →1.8では、"1あア"となりますが、1.9では、"1あアあ"となります。 <問題2> ■文字列の中から指定文字が見つかったバイト位置の算出 □現在(Ruby1.8)のコード n = "あいうえお".index("う") →1.8では、n=4となりますが、1.9では、n=2となります。 <問題3> ■指定した年月日の存在チェック □現在(Ruby1.8)のコード y = 1900 m = 3 d = 10 if Date.exist?(y,m,d) p "test# end →1.8では、trueとなりますが、1.9では実行時にNoMethoodErrorとなります。 <問題4> ■半角英数字→全角英数字変換 □現在(Ruby1.8)のコード sss = moji.tr('a-zA-Z0-9', 'a-zA-Z0-9') →1.9では実行時にエラーメッセージが出力されます(略) 色々と書きましたが、どうかお助けください。

    • ベストアンサー
    • Ruby
  • unicode と shift_jis

    テキストファイルを読み込みデータを作成して出力するプログラムを作成しているのですが国際化させることになりました。そこで問題が‥テキストファイルが日本用はshift_jis、海外用はunicodeで構成されています。shift_jisでの文字列操作は良いとしてunicodeが全然わかりません。海外向けを想定したときに気をつけなければならないこともわかりません。なんでもいいので教えてください。お願いします。特に、unicodeの文字列操作はまったくよくわかりませんので細かい点から教えていただけると光栄です。よろしいお願いします。

  • Rubyによる文字抽出

    こんにちは。1週間ほど前からRubyを始めた者です。 任意の文字列から指定したIndexの1文字を取り出したいのですが、 s = "Apple" puts s[0] のようにすると実行結果は 65 となってしまいます。本当は"A"と出て欲しいのですが。 65とAは一対で対応しているのだと思いますが、文字そのものを出すにはどうしたらよいのでしょう? どなたかご教授頂けないでしょうか?

  • 文字列を quoted-printable 文字列に変換したい

    例えばShift_JISの文字列をquoted-printable文字列に変換したいのですが、IMAP関数を使わずに行うことはできないものでしょうか? PHPを使ってvcalendarファイルを作りたいと思っているのですが、今借りているレンタルサーバではimap_8bit関数が使えないもので。

    • ベストアンサー
    • PHP
  • Rubyについての質問です

    Rubyでちょっとわからないことがあって、マニュアルを見ても解決しなかったので、こちらに質問しました。 たとえば a = 10 puts "Answer" puts a というソースがあったとして、これを実行すると Answer 10 と出力されます。 ここで質問なんですが、aという変数を用いて Answer = 10 のように出力するにはどうしたらいいのでしょうか? たとえばJavaだったら int a=10; system.out.print("Answer" + a); と同じような出力結果にしたいんです。

  • [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"]

  • 最終列の列番号を列文字に変換することはできますか?

    例えばaaaがある列を探し、その列番号は4で列文字がDですが、 列番号から列文字をvbaで取得する方法はありますか? Sub Sample() Dim i As Long Dim Colmoji As String i = Rows(1).Find(What:="aaa", LookAt:=xlWhole).Column Colmoji = i 'ここで列文字に変換したい MsgBox i & "の列文字は" & Colmoji & "です" End Sub このようなコードを作ってみたのですが列文字に変換する方法がわかりません。

  • 文字列比較

    最長10文字の文字列を2件入力し、char型の配列にそれぞれ格納する。2つの文字列を比較し、文字列が同じだったら「equal」を表示し異なっていたら「Not equal」を表示するプログラムを作成せよという課題が出ました。 条件として、11文字以上の文字が入力されたら、先頭から10文字までを有効とし、11文字目以降を無視する。下記のプログラムで文字列1に11文字以上入力すると、うまく動きません。なぜ、うまくいかないかと、どうなおしたらよいかを教えてください。 #include<stdio.h> #include<string.h> #define max_length 10 void get_string (char *p_str, int size); int main() { char string1[max_length+2]; char string2[max_length+2]; printf("文字列1:"); get_string(string1,max_length+2); printf("文字列2:"); get_string(string2,max_length+2); if(!strncmp(string1,string2,max_length)) puts("equal"); else puts("Not equal"); } void get_string (char *p_str, int size) { fgets(p_str,size,stdin); }

  • 文字列の10+10を20と表示したい

    はじめまして。 データーベースのstring型フィールドに10+10と文字列で入っています。 そのままprintで出力すると10+10と表示されます。 そうではなく20とprintで表示するにはどうすればいいのでしょうか。 intval関数やeval関数等自分で思考錯誤したのですが、どうしても、20と表示されません。 どのようにすればいいのか、ぜひ教えてください。

    • ベストアンサー
    • PHP

専門家に質問してみよう