WindowsとLinuxで動作が異なる?解決法を教えてください

このQ&Aのポイント
  • WindowsとLinuxで同じスクリプトを動かしたら、動作が異なることがあります。
  • Windowsで動かすと最後まで動くのに対し、Linuxで動かすとループの2週目で止まってしまいます。
  • このような現象はよくあるので、解決法を教えてください。
回答を見る
  • ベストアンサー

WindowsとLinuxで動かしたときの動作が違ってしまいます

以下のスクリプトをWindowsで動かしたときにはちゃんと最後まで動くのに対し、Linuxで動かすとループの2週目でとまってしまいます。 こういうことって結構よくあることなんですか?? 解決法などご存知の方いたら教えてください ーーーーーーーーーー PKTMP="C6C6nCCnnnCCnC4C4" HEADLEN=34 ST = Struct.new(:tomac,:frommac,:toip,:fromip,:ttl,:prot,:data) def analyze(data)  result = Array.new  i=0  while data   head = data.unpack(PKTMP)   if (head[12] != 0x800) || (head[13] != 0x45)    result << "error! in No.#{i} packet"    return result   end   tmp = ST.new   tmp.tomac = macaddr(head,0)   tmp.frommac= macaddr(head,6)   tmp.toip = ipaddr(head,-8)   tmp.fromip=ipaddr(head,-4)   tmp.ttl = sprintf("%d",head[18])   tmp.prot = sprintf("%d",head[19])   data.slice!(0...HEADLEN)   datalen = head[15] - (head[13] & 0xf)*4   tmp.data = data.slice!(0...datalen)   result << tmp   i+=1  end # end of (while data )  return result end

  • Ruby
  • 回答数5
  • ありがとう数17

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4845/10255)
回答No.5

#1,#2,#4です。すいません。さっきの半分無しにしてください。 開発版の1.9.0を使うべきでないと言うところは良いのですが、原因は、Rubyの不具合じゃなくて、1.8系と1.9系の仕様の違いですね。 1.9系では、slice!を初めとする「文字列の一部を数字で位置指定する」機能が変更になってます。 1.8系がバイト単位で、1.9系が文字単位です。指定しないとデフォルトがUS-ASIIだから同じだろうと思っていましたが、何も指定しないでファイルから読むと、OSの標準(Linuxだと環境変数LANG)の文字コードになります。なお、US-ASCIIだと\x80~\xFFのバイトがエラーに。 1.9系のRubyを使うのなら、プログラム先頭で、 Encoding.default_external = "BINARY" if RUBY_VERSION > "1.9" としてください。

RekCah1991
質問者

お礼

ありがとうございます。 ちゃんとバイナリ単位でデータをやり取りできるように修正したいと思います

その他の回答 (4)

  • notnot
  • ベストアンサー率47% (4845/10255)
回答No.4

#1,#2です。 失礼しました。 1.9.0のRubyというのは、テストされてリリースされたものではなく、開発版です。開発途上版というか、よくベータ版ソフトとかありますが、ベータ版ですらなくて、「こういう機能を追加・変更してみました」的に、日々プログラムが書き換えられています。Rubyインタプリタやライブラリの開発者が使うものです。 2008-06-20版がどういう変更を加えられたものかはわかりませんが、お使いの機能の部分の機能変更や処理ロジック変更があった直後であれば、テストが足りてない可能性があります。 実用で使うのであれば、リリース版である、1.8.6 か 1.8.7 か 1.9.1 を使ってください。 特徴は、 1.8.6 → 現在の書籍はほとんどこれに準拠。バージョンを指定せず公開されているソフトもまず間違いなく動く。 1.8.7 → 1.8.7 に 1.9系の一部新機能を追加したもの。1.8.6 と(100%ではないが)上位互換性がある。 1.9.1 → 高速化されて、機能追加や、文字コードその他の機能変更。まだ新しいバージョンなので、公開されているソフトが全部動くわけではない。これに準拠した書籍も少ない。 Linuxのパッケージ管理システムでインストールされるのは、ほとんど(orすべて)のディストリビューションで今のところ1.8.6だと思います。 1.9.0が入っていると言うことは、誰かがソースからコンパイルしてインストールしたものですね。

RekCah1991
質問者

お礼

ありがとうございます Rubyのバージョンを変えたらちゃんと動くようになりました 自分がちゃんと開発バージョンかどうかをチェックしなかったのが悪かったんですね。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

Windowsとlinuxで動きが違う、と言われて、まっさきに思い浮ぶのは、改行とエンコーディングですが.... データの読み出しをテキストモードでやってるとかはありませんか?

RekCah1991
質問者

お礼

それも大丈夫です 問題の関数をrequireしているのが↓です。 自分はこのスクリプトに引数を与えて起動したのでちゃんと"rb"で開けているはずだと思います。 あと、このスクリプトを(動かなかったPCじゃない)他のLinuxのPCにさして 同じようにやってみたらそっちはちゃんと動きました。 ちなみに動かなかったほうのRubyのバージョンは ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux] なんですが、このバージョンには何か特別な問題でもあるんでしょうか? ------main.rb------------ require "analyze.rb" input = open(ARGV.shift,"rb") output = STDOUT data = input.read res = analyze(data) res.each{|packet| p packet }

  • notnot
  • ベストアンサー率47% (4845/10255)
回答No.2

>ということはRubyのバグと見ていいんでしょうか?? Rubyにバグはまだあるでしょうけど、こういう簡単なレベルでは出てきません。 おそらくは、データのコピーミスとか、テストミス、確認ミスなどが原因です。 あと、 while data だと無限ループになるので、 while data != "" として、dataが空文字列になったら終了した方がよくないですか?

RekCah1991
質問者

お礼

ループの件はおっしゃるとおりです。 ありがとうございます。 WindowsとLinuxの二つの環境で試したというのは、 一つのUSBメモリの中に解析するデータとこのスクリプトを入れて そのUSBメモリをWindowsにさして中身を実行、 次にLinuxのPCに差し変えて実行、 というようにやったのでデータのコピーミスとかは無いはずだと思います

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

書かれている範囲では、WindowsとLinuxで動作の違う機能は無いので、データが同じなら動作も同じはずです。

RekCah1991
質問者

お礼

ありがとうございます。 やはり違いは無いんですね。 ということはRubyのバグと見ていいんでしょうか??

関連するQ&A

  • javascript

    var sum = function(){ var result = 0; for(var i = 0; i < arguments.length; i++){ var tmp = arguments[i]; result += tmp; } return result; } document.writeln(sum(1, 3, 5, 7, 9)); このプログラムと function sum(){ var result = 0; for(var i = 0; i < arguments.length; i++){ var tmp = arguments[i]; result += tmp; } return result; } document.writeln(sum(1, 3, 5, 7, 9)); このプログラムでは実行結果は同じですが、 どちらのほうが良いプログラムなのでしょうか?

  • Ruby バブルソート

    バブルソートのプログラムでわからないところがあるため、 質問させていただきます。 Rubyは1.9.3を使用しています。 <プログラム> --------------------------------------------------- def bsort(data)   while true     # swapped変数は数値の入れ替えを記憶     swapped = false     for i in 0..data.size-2       if data[i] > data[i+1]         temp = data[i]         data[i] = data[i+1]         data[i+1] = temp         swapped = true       end     end     return if !swapped   end end data = [10, 9, 8, 7, 6] bsort(data) puts "ソート結果#{data}" --------------------------------------------------- return if !swapped のところで、 なぜwhileのループから抜けられるのかがよくわかりません。 return if swapped == false と書き換えて実行しても同じ結果が得られたのですが、 数値の入れ替えがなければ swapped = false であるため、 !swappedはtrueとはならないのでしょうか。

  • javaへの変換

    class Integer def prime? n = self.abs() return true if n == 2 return false if n == 1 || n & 1 == 0 d = n-1 d >>= 1 while d & 1 == 0 20.times do a = rand(n-2) + 1 t = d y = ModMath.pow(a,t,n) while t != n-1 && y != 1 && y != n-1 y = (y * y) % n t <<= 1 end return false if y != n-1 && t & 1 == 0 end return true end end module ModMath def ModMath.pow(base, power, mod) result = 1 while power > 0 result = (result * base) % mod if power & 1 == 1 base = (base * base) % mod power >>= 1; end result end end 上記プログラムをjavaで書き直して頂きたく投稿いたしました。 もしよろしければお願いします。

  • JavaScriptで全くの初心者なのですが、

    JavaScriptで全くの初心者なのですが、 フィッシャーイェーツのシャッフルをaのリスト内でしてから、 そこから一つ値をとり、 別の関数内で、その関数内での新たな変数に代入するようにしたいです。(function(){var b = this.result;}のような) プログラミングはやらないのに急に使うことになり困っているのでだれか助けてください。 a = [1,1,1,5,5,5,9,9,9]; for (var a=[],i=0;i<9;++i) a[i]=i; this.result = a[shuffle(a.length)] ; function shuffle(array) { var tmp, current, top = array.length; if(top) while(--top) { current = Math.floor(Math.random() * (top + 1)); tmp = array[current]; array[current] = array[top]; array[top] = tmp; } return array; }

  • ポインタ

    質問なのですが、このソースのchar *str_copy(char *d, const char *s)関数内のchar *p=d;はなんで、*pにdを入れるか分かりません。それと、このdは、*dなのですか?どうして、while (*d++ = *s++) みたいに*dをつけないんですか?教えてください。宜しくお願いします。 #include <stdio.h> char *str_copy(char *d, const char *s) { char *p=d; while (*d++ = *s++) ; return (p); } int main(void) { char tmp[100]; char st1[100], st2[100],st3[100]; printf("文字列を入力してください:"); scanf("%s",tmp); str_copy(st1,str_copy(st2,tmp)); printf("文字列st1は%sです。\n", st1); printf("文字列st2は%sです。\n", st2); printf("文字列st3は%sです。\n", str_copy(st3,tmp)); return (0); }

  • ソートについて

    以下のプログラムを実行すると整数のソート結果が "1","12","3"となってしまいます。 整数と文字列を分離させてそれぞれソートさせたいのですが 方法がわかりません。 import java.util.*; import java.io.*; class StrArray{ ArrayList list = new ArrayList(); //最下行に要素を追加 public void add(String data){ list.add(data); } //全ての要素を配列で所得 public String[] getAll(){ String[] all = new String[list.size()]; for(int i=0; i<list.size(); i++){ all[i] = super.get(i); } return all; } public static final int ASC_SORT = 0; public void sort(int mode){ ArrayList al = this.qsort(mode, list); al = list; } //クイックソート public ArrayList qsort(int mode, ArrayList data){ ArrayList result = new ArrayList(); if(data.size()<1){ return new ArrayList(); } String middle = (String)data.get(data.size()/2); ArrayList left = new ArrayList(); ArrayList right = new ArrayList(); for(int i=0; i<data.size(); i++){ if(i != data.size()/2){ if(mode == 0){ if(((String)data.get(i)).compareTo(middle)<=0){ left.add(data.get(i)); } else{ right.add(data.get(i)); } result.addAll(qsort(0, left)); result.add(middle); result.addAll(qsort(0, right)); return result; } return result; } } } } class Sample{ public static void main(String args[]){ StrArray alist = new StrArray(); alist.add("bbb"); alist.add("aaa"); alist.add("ddd"); alist.add("ccc"); alist.add("3"); alist.add("1"); alist.add("12"); alist.sort(0); String[] info = alist.getAll(); for(int i = 0; i < info.length; i++){ System.out.println(info[i]); } } }

  • リスト構造のプログラミング

    #include<stdio.h> #include<stdlib.h> typedef struct number{ float x; struct number *next; }Num; void append_list(Num **, float); int main(void) { Num *start,*p; float i,d; start=NULL; for(i=0.0;i<10.0;i++){ append_list(&start,i); } p=start; while(p!=NULL){ printf("%f\n",p->x); p=p->next; } p=start; while(p !=NULL){ Num *q; q=p; p=p->next; free(q); } return 0; } void append_list(Num **s, float n) { Num *end, *new; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*s)->x=n; (*s)->next=NULL; return; }end=(*s); while(end->next !=NULL){ end=end->next; } new=(Num *)malloc(sizeof(Num)*1); new->x=n; new->next=NULL; end->next=new; } 0~9までの数値を順番に追加してリスト構造のデータ構造で 保存するプログラミングを作ったのですが、これにキーボード から入力した1つの実数(0~9)を数値の順序を乱さないよう にその数値を持つ要素を追加するにはどうすればよいのでしょうか?

  • PHP 全角文字が文字化けまたは表示されない

    PHPでエクセルで作成したcsvファイルから商品一覧を表示させたいのですが。 一覧ページで日本語や大文字英数が含まれるデータが表示されません。 エンコードはいろいろ試してみたのですが、utf-8だと文字化け、EUC_JPやSJISだと表示されなくなってしまいます。 csvから呼び出す際に mb_convert_variables('utf-8', 'sjis-win', $tmp); としても文字化けします。 ちなみに、$dataでprintすると問題なく表示されます。 $data1では上手く表示されません。 なので、for($i=$start;$i<$end;$i++){ 以降でおかしいんだろうなとは思うのですが。 1ページに数件ずつで、次へ次へで移りたいので、ここの部分が必要です。 商品詳細ページで、同じcsvファイルを読みだしてますが、 while ($data = fgetcsv($fp, 10000)) { if($atai==$data[0]){ ・・・・ と書いてこちらは問題なく表示できています。 何が原因か見つけられずに困っています。 お分かりになる方、教えてください。 初心者レベルですので、なるべく具体的に書いていただけると助かります。 よろしくお願いします。 //ファイルからデータを読み込む処理 function inst_view($page=0) { //読み込むファイル名 $filename = FILE_PATH; //データ数をカウントする $row = 0; $data = array(); //CSVファイルの中身をすべて読み込む $handle = fopen($filename, "r"); while (($tmp = fgetcsv($handle, 1000, ",")) !== FALSE) {    if (!empty($choice1) && $choice1 == "4") { $num = count($tmp); if( $tmp[0] == "" ){ }else{ $data[$row]["no"] = $tmp[0]; $data[$row]["hito"] = $tmp[1]; $data[$row]["kuni"] = $tmp[2]; $data[$row]["tochi"] = $tmp[3]; $data[$row]["nen"] = $tmp[4]; $data[$row]["size"] = $tmp[5]; $data[$row]["cm"] = $tmp[6]; $row++; } } } fclose($handle); //降順にする rsort($data); //1ページに表示するデータ数を読み込む $page_length = PAGE_LENGTH; //全ページ数を求める処理 $maxpage = $row/$page_length; $tmp = (int)$maxpage; if($maxpage>$tmp){$maxpage=$tmp+1;} $maxpage--; //現在のページ数からデータ開始と終わりを求める $start = $page * $page_length; $end = ($page * $page_length) + $page_length; //データを格納する配列と、その指標 $cnt=0; $data1 = array(); //データ格納処理(スタートからエンドまで繰り返す。 for($i=$start;$i<$end;$i++){ //最大データ数を超えたら取得終了する。 if($i >= $row){break;} $data1[$cnt]["no"] = $data[$i]["no"]; $data1[$cnt]["hito"] = $data[$i]["hito"]; $data1[$cnt]["kuni"] = $data[$i]["kuni"]; $data1[$cnt]["tochi"] = $data[$i]["tochi"]; $data1[$cnt]["nen"] = $data[$i]["nen"]; $data1[$cnt]["size"] = $data[$i]["size"]; $data1[$cnt]["cm"] = $data[$i]["cm"]; $cnt++; } return $data1; } 別のファイルからinst_viewを呼び出しています。

    • 締切済み
    • PHP
  • StringTokenizerについて

    JAVAの勉強をしているのですが、StringTokenizerの役割がよく分かりません。検索サイトを使って色々調べてみたのですが、「トークンを区切る」だとかよく分からない言葉が出てきて全く理解できません。以下はあるデータから項目を抽出するプログラムらしいのですが、参考としてこの例でStringTokenizerがどのような役割を果たしているのか教えて下さい。複雑で説明しにくければStringTokenizerそのものの説明でも十分です。よろしくお願いします。 BufferedReader reader=new BufferedReader(new InputStreamReader(System.in)); String line=""; try { int i=0; while ((line = reader.readLine()) != null) { int fcount=1; StringTokenizer st = new StringTokenizer(line); while (st.hasMoreTokens()) { switch (fcount) { case 2: //項目2:被説明変数Y data[i][0]=Integer.parseInt(st.nextToken()); break; case 4: //項目4:説明変数X data[i][1]=Integer.parseInt(st.nextToken()); break; default: // その他の項目 String dummy=st.nextToken(); break; } fcount++; } i++; } NofData=i;

    • ベストアンサー
    • Java
  • クイックソートプログラムでセグメンテーション違反がでるのですが

    クイックソートのプログラムを作成したのですが、 実行するとセグメンテーション違反が発生して、上手くいきません。何処に原因があるのでしょうか? また、セグメンテーションン違反とはどういったころなのでしょうか? アドバイス宜しくお願いします。 #include <stdio.h> int quick_sort(int *a,int start,int end); int partition(int *a,int start,int end); main() { int n; int a[n]; int i; printf("ソートしたい要素の個数は?\n"); scanf("%d",&n); for(i=0;i<=n-1;i++) a[i]=0; for(i=0;i<=n-1;i++){ printf("%dのデータを入力してください。\n",i+1); scanf("%d",&a[i]); } printf("ソート前のデータは以下の通り\n"); for(i=0;i<=n-1;i++) printf("%d ",a[i]); quick_sort(*a,1,n-1); printf("ソート後のデータは以下の通り\n"); for(i=0;i<=n-1;i++) printf("%d ",a[i]); } int quick_sort(int *a,int start,int end) { int pivot; if(end-start>0){ pivot=partition(a,start,end); quick_sort(a,start,pivot-1); quick_sort(a,pivot+1,end); } } int partition(int *a,int start,int end) { int i,j,pivot,tmp; i=start-1; j=end; pivot=a[end]; while(1){ while(a[++i]<pivot); while(i<--j && a[j]>pivot); if(i>=j) break; tmp=a[i]; a[i]=a[j]; a[j]=tmp; } a[end]=a[i]; a[i]=pivot; return i; }

専門家に質問してみよう