• ベストアンサー
  • すぐに回答を!

同じデータファイルなのに、linuxとMacで値が違ってしまうのはなぜ?

職場でlinux(初心者です), 自宅でMacを使っています。 同じCプログラムを使って、同じバイナリデータファイルから数値を読み出したところ、職場のlinuxでやった場合と自宅のMacでやった場合では、違う値が出てきてしまいます。読み込むデータは1byteのバイナリなので、エンディアンは関係ないと思うのですが、ほかに原因があるのでしょうか?そばに詳しい人がおらず、困っています。どうしてこういうことが起きるのか、また、どうやったら解決できるのか、どなたか詳しい方、ぜひアドバイスをお願いします。 以下、プログラムの説明とプログラムの一部です。 バイナリデータファイルから、dposition[i]番目の1byteのデータをそれぞれ読み込み、それぞれ別の出力ファイルfo[i]に書き込みます。dposition[i]はPOSITION_NUM個あり、従って、出力ファイルもPOSITION_NUM個用意しています。dposition[i]で指定した場所はとびとびの不連続な場所です。データを読み込むときは、0番目から、一番大きいdposition[i]番目(=maxnum番目)のデータまで、すべてをarray[datanum]に読み込み、書き出すときにdposition[i]番目のデータのみを書き出すよう指定しています。読み込むバイナリファイルはFILE_NUM個あり、すべて同じ形式です。順次開いて読み込み出力を繰り返します。以下プログラムの一部です。 for (j = 0; j < FILE_NUM; j++) { if(NULL == (fi = fopen(fn_in[j],"rb"))) { printf("Cannot open input BISE File\n"); exit(1); } for (datanum = 0; datanum < maxnum+1; datanum++) { array[datanum] = fgetc(fi); } for (i = 0; i < POSITION_NUM; i++) { fprintf(fo[i],"%d\n",array[dposition[i]]); } fclose (fi); } 以下、linuxでやった場合の出力を左、Maxでやった場合の出力を右に並べて書きます。 104 104 100 100 74  22 83  83 60  60 0   0 106 106 79  33 167 167 182 182 180 0 188 188 ... ... 3,8,11番目が違う数字が出力されます。繰り返しますが、プログラムと入力ファイルは同じものです。 linuxでもMacでもターミナルでコンパイル、実行しています。 コンパイラのバージョンは、gccで検索したらなんだかたくさん出てきてしまって、どれが使っているコンパイラのバージョンなのかよくわかりませんでした。 ちなみに、MacはIntel系の方です。 ほか、アドバイスいただくにあたって、何か必要な情報があればご指摘ください。 ぜひよろしくおねがいします。

共感・応援の気持ちを伝えよう!

  • 回答数4
  • 閲覧数93
  • ありがとう数5

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

  • ベストアンサー
  • 回答No.1

バイナリファイルの実際の内容はどうなっているのでしょうか? macとlinuxで結果が異なるということよりも、どちらが間違っているのか、あるいは両方とも間違っているのか、どうなんでしょう。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

odというコマンドでバイナリの中身が直接みられることがわかり、確かめてみました。すると、macとlinuxでは、そもそもインプットファイルの該当部分の値が違ってることがわかりました。。。 全く同じファイルをコピーして使ったはずなんですが。。。 インプットファイルをコピーし直してやり直したら、どちらのPCでもちゃんと同じ値がでてきました。 しょうもない理由ですみませんっっ 皆さん、いろいろとお返事どうもありがとうございましたm(_ _)m

関連するQ&A

  • Linuxについて

    Linuxのスクリプトについて Linuxのスクリプトについての質問です #/bin/sh n=$1 while [ $n -le $2 ]; do echo "year $n" cal $n n=`expr $n + $3` done という引数に応じてカレンダーを出力するスクリプトを作成しました。 このスクリプトは引数が2つの場合は、1年ごとのカレンダーが表示されます。 ここに、引数が2つより少ないときはエラーメッセージを出力してプログラムを終了する機能をつけたいのですが 方法がよくわかりません。 #!/bin/bash # 実行時に指定された引数の数、つまり変数 $# の値が 3 でなければエラー終了。 if [ $# -ne 3 ]; then echo "指定された引数は$#個です。" 1>&2 echo "実行するには3個の引数が必要です。" 1>&2 exit 1 fi # ヒアドキュメントでメッセージを表示する。 cat <<__EOT__ 指定された引数は、 $1 $2 $3 の$#個です。 __EOT__ exit 0 このスクリプトをなんとか応用すればできると思うのですが なにせ初心者なもので;; ちょっと複雑になるとすぐに頭が混乱してしまう所存です・・・ どなたかご親切な方のご回答をお待ちしています。

  • 急にプログラムが正しく動かなくなってしまった

    Macのターミナルでcのプログラムを動かしています。 今まで使えていたプログラムが、突然うまく動かなくなりました。 原因が分からないのですが、どなたかアドバイスいただけないでしょうか? プログラムは、 1)ファイル名のリストを読み込んで、 2)読み込んだ名前のバイナリファイルを全て開き 3)それらのファイルからデータを読み込んで処理 というものです。 このプログラムは同じパソコン上でもともと正しく動いていたのですが、あるとき突然、2)の段階で一部のファイルが開けなくなってしまいました。 原因を探るために、ファイルを開いて閉じるだけのプログラムに削ってみましたが、やはり症状は変わりませんでした。 同じプログラムを、別のパソコン(windows+cygwin)にコピーしてみると、ちゃんと動きます。使用中のMacに何か問題があるのかなとおもうのですが、原因が分かりません。 詳しい状況と、開いて閉じるだけの状態に削ったプログラムを以下にのせておきます。どなたか原因が分かる方、ぜひアドバイスをお願いします。 [状況] ・上記2で開きたいバイナリファイルは332個あるのですが、253個しか開けず、それ以降はCannot open (ファイル名)のメッセージが出ます(そういうメッセージを出すようなプログラムにしてあります) ・上記2でfopenの前に、これから開くファイル名を表示させてみると、ファイル名は全て正しく読み込めています。 ・開きたいバイナリデータファイルが壊れていることを想定し、バックアップからコピーし直してみましたが、やはり症状はかわりません。 ・ for (i = 0; i < FILE_NUM; i++) をつかって複数ファイルを開いていますが、最初をi=0とすると1個目から253個目までしかファイルが開けず、最初をi=1とすると、2個目から254個目のファイルまで開けますが、それ以降のファイルはやはり開けません。どういう訳か、253個だけしかファイルが開けないのです。 [プログラム] #include <stdio.h> #include <stdlib.h> #include <string.h> #define FILE_NUM 332 #define DataDir "../N2913S5601W2689E4705" #define FileList "list_BISE3.txt" #define BUFFER 256 main() { char fn[FILE_NUM][BUFFER]; FILE *fp[FILE_NUM], *fi; char buffer[BUFFER]; unsigned short i; char *p; fi = fopen(FileList, "r"); if (!fi) { printf("Cannot Open %s\n",FileList); exit(1); } for (i = 0; i < FILE_NUM; i++) { p = fgets(buffer, BUFFER, fi); if (!p) { break; } p = strchr(buffer,'\n'); if(p != NULL) { *p = '\0'; } sprintf(fn[i], "%s/%s", DataDir, buffer); printf("%s_\n",fn[i]); fp[i] = fopen(fn[i], "rb"); if (!fp[i]) { printf("Cannot Open %s\n", fn[i]); continue; } } fclose(fi); for (i = 0 ; i < FILE_NUM; i++) { fclose(fp[i]); } }

  • C言語のバイナリモードでのfscanf関数の使い方について教えて下さい

    C言語のバイナリモードでのfscanf関数の使い方について教えて下さい。 2*2のint型配列バイナリデータを読み込んで、要素一つ一つを出力したいのですが、 fscanfでの書式指定の仕方がよく分かりません。 fscanf(入力元,"???",&入力先)の???の部分はどう指定すればよいのでしょうか? 下記のようなプログラムを書いたのですが、fscanfでデータを読み込めず、 data=0という出力で無限ループに入ってしまいます。 C言語初心者なので、かなり初歩的な質問かと思いますが、 よろしくお願いします。 -------------------------------------- char *fi; int data; fi = argv[1]; /* 2x2のint型配列バイナリデータを指定 */ input = fopen(fi,"rb"); while(!feof(input)){ fscanf(input,"%d",&data); printf("data=%d\n",data); } ---------------------------------------

その他の回答 (3)

  • 回答No.4
  • Tacosan
  • ベストアンサー率23% (3656/15482)

大前提として「Mac と Linux で同じ内容として読み込めている」のであれば, #2 にあるように dposition の値があやしいような気がします. ちなみに gcc のバージョンは gcc -v と実行したときの最後の行にあります.

共感・感謝の気持ちを伝えよう!

質問者からのお礼

odというコマンドでバイナリの中身が直接みられることがわかったので、インプットファイルの中身を確かめてみたら、そもそも両PCでインプットファイルの該当部分が違ってることがわかりました。。。 同じファイルをコピーしたはずなんですが。。。 しょうもない理由ですみませんっ! gcc -v の情報、ありがとうございます。 一つ勉強になりました。 お返事どうもありがとうございましたm(_ _)m

  • 回答No.3
  • shred
  • ベストアンサー率35% (25/70)

>linuxでやった場合の出力を左、Maxでやった場合の出力 これはエディタで閲覧したものか、10進数表記したものどちら? あなたはバイナリファイルと言っている。そしてrbモードでオープンしている。しかし読み書きはfgetc,fprintfを用いている。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

odというコマンドでバイナリの中身が直接みられることがわかったので、インプットファイルの該当部分の値を確かめてみたところ、両PCでそもそもインプットファイルの該当部分の値が違ってることがわかりました。。。 全く同じファイルをコピーして使ったはずなんですが。。。 しょうもない理由ですみませんっっ ちなみに、インプットはバイナリ、アウトプットは10進数表示のテキストで、表示した値はテキストのアウトプットファイルの中身でした。 お返事どうもありがとうございましたm(_ _)m

  • 回答No.2
  • php504
  • ベストアンサー率42% (926/2160)

dposition[ ] 配列の中身がlinuxとMacで違うとしか思えません fprintf(fo[i],"%d\n",array[dposition[i]]); を fprintf(fo[i],"dposition=%d:%d\n", dposition[i], array[dposition[i]]); にして確認してみては

共感・感謝の気持ちを伝えよう!

質問者からのお礼

odというコマンドでバイナリの中身が直接みられることがわかったので、アドバイスいただいた方法でdpositionの中身を確かめ、インプットファイルの該当部分の値を確かめてみました。すると、macとlinuxでは、そもそもインプットファイルの該当部分の値が違ってることがわかりました。。。 全く同じファイルをコピーして使ったはずなんですが。。。 しょうもない理由ですみませんっっ お返事どうもありがとうございましたm(_ _)m

関連するQ&A

  • 入れ子で検索

    初心者です。 $time,$number,$data(実験回数、データ番号、データ) という3列のデータを、実験回数毎に同じデータ番号のデータを出力するプログラムを組もうとしています。データ数は回数、データ番号毎に同数あり、データ番号は実験毎に1から振られています。 出力結果としては↓の様にしたいと思っています。 実験回数、データ番号、データ、データ、データ しかし、データ数が多すぎて、データをpushして配列にしすぎたり、データ番号をハッシュにするとPCがメモリ不足になるため、forの入れ子にして、毎回データを読む様にしました。 for(my $time_n = 1; $time_n <= $input; ++$time_n){ #$inputは最大実験回数 for(my $n = $data_num * ($time_n - 1) + 1 ; $nn <= ($data_num * $time_n) ; ++$nn){ #$data_numは実験1回分のデータ番号数、 @array = (); while ($line = <FILE>) { chomp $line; ($time,$number,$data) = split /,/, $line; if($number == $n){ push @array, $data; } } print OUT3 "$time_n,$array[0],$array[1],$array[2]\n"; } } これでやってみると、実験回数1回目しかうまく出ません。なぜでしょうか? どなたか教えて下さい。 宜しくお願いします。

    • ベストアンサー
    • Perl
  • バイナリデータについて

    バイナリデータについて 先日関連した質問をさせていただいただのですが、 質問内容があやふやでしたのであらためて 今回POS連携システムにてPOSへ渡すデータを固定長バイナリ型式で作成いたします。 JAVAにてデータ作成を行うのですが、その作成方法がよくわかりません。 例えば次の6項目があるとして 元のデータ[0001] → 属性[K] 長さ[2Byte] 元のデータ[20100901] → 属性[K] 長さ[4Byte] 元のデータ[1234567890123456ffff] → 属性[K] 長さ[10Byte] 元のデータ[000100] → 属性[P] 長さ[3Byte] 元のデータ[0000001c] → 属性[P] 長さ[4Byte] 元のデータ[01] → 属性[B] 長さ[1Byte] 元のデータから各属性への変換、ファイル出力がイメージがわきません。 属性のK,P,Bというのもよくわかりません。 どなたかヒントでもいただけたら幸いです。 よろしくお願いいたします。

    • ベストアンサー
    • Java
  • fopenしてくれない。。。

    こんにちは。PHP初級者です。 postgresqlに入れたデータをCSVファイルに書き込んで、出力してみたいと思って以下のプログラムを作ってみました。 $file_name ="insatu.csv"; //データベースから呼び出し以下の$arrayへいれるデータは省略します。 //今回は1行のみのデータを入力プログラムになってますが、本当は何行もやるプログラムとなってます。 $array = compact("a","b","c","d","e","f","g","h","i","j","k","l"); $string = implode("," , $array); $file = fopen($file_name, "a") or die ("openエラー $file_name"); flock($file, LOCK_EX); fputs($file, $string."\n"); flock($file, LOCK_UN); fclose($file); $file = fopen($file_name, "r"); while($array = fgetcsv($file, 1000, ",")){ echo "<hr> \n"; for($i=0; $i< count($array); $i++){ echo $array[$i]."<br>"; } } fclose($file); なぜか最初の fopenで dieの方へ行って OPENエラーメッセージが出てきます。 この作業をするためには何かあらかじめ入れなくてはいけない構文とかあるんでしょうか?何か間違っていますでしょうか? それともphp.iniを設定するとかしなくてはいけないんでしょうか? php5を使用してますが、php.iniやphp.ini-distはともに見つからず。 困り果ててます。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 問題: 以下の2つのプログラムを実装し、時間計算量を実験的に評価せよ。

    問題: 以下の2つのプログラムを実装し、時間計算量を実験的に評価せよ。     (1)1から1万までの整数ちをランダムに1千個生成するプログラム     (2)シェルソートプログラム 質問内容   プログラム()をやったんですが、「時間計算量を実験てきに評価せよ」というのは分かりません。 教えてください。 /* ランダムプログラ*/ #include<stdio.h> #include<stdlib.h> #include<time.h> #define N 1000 void main(){ FILE *fp; int i,rnd; fp=fopen("data.dat","w"); srand((int)time(NULL)); for(i=1;i<=N;i++){ rnd = (int)rand()% 10000 + 1; fprintf(fp,"%d\n ", rnd); } fclose(fp); } /* シェルソートプログラム*/ #include <stdio.h> #include <stdlib.h> #define DATA_NUM 1000 void ShellSort(int num[ ], int n) ; void InsSort(int num[ ], int gap, int n); void ShowData(int num[ ], int n); void main(void); /* n 個のデータのシェルソートを行う */ void ShellSort(int num[ ], int n) { int gap; for (gap = n / 2; gap > 0; gap /= 2) InsSort(num, gap, n); } /* n 個のデータの単純挿入ソートを行う */ void InsSort(int num[ ], int gap, int n){ int i, j, temp; for (i = gap; i < n; i ++) { for (j = i - gap; j >= 0; j -= gap) { /* このループで */ if (num[j] <= num[j + gap]) /* j 番目とj + gap 番目と比較 */ break; /* ここにbreak;を挿入。*/ else { temp = num[j]; /* 要素の入れ替え */ num[j] = num[j + gap]; num[j + gap] = temp; ShowData(num,DATA_NUM); /* 途中経過を表示 */ } } } printf("\n"); /* InsSort( ) を抜ける時改行 */ } /* n 個のデータの表示 */ void ShowData(int num[ ], int n) { while (n--) printf("%d ", *num++); printf("\n"); } void main(void) { FILE *fp; int data[DATA_NUM]; int i; fp = fopen("data.dat","r"); if(fp == NULL){ printf("data.dat cannot be opened"); exit(1); } for(i=0;i<DATA_NUM;i++){ if(fscanf(fp,"%d",&data[i])== NULL){ break; } } printf("ソート前\n"); ShowData(data, DATA_NUM); printf("\n"); /* シェルソート */ ShellSort(data, DATA_NUM); printf("\n"); printf("ソート後\n"); ShowData(data,DATA_NUM); printf("\n"); fclose(fp); }

  • int型で取得したSJISをchar型に変換する方法

    タイトルの件についてお聞きしたいのですが、 バイナリデータの 61 を a として出力しましたがうまくいきません。 ----------------------------------------------------- int moji; //バイナリデータを開く FileInputStream fi = new FileInputStream("ABC.MGR"); //バイナリデータ(仮に 61 = a ) を取得する。 moji = fi.read(); ----------------------------------------------------- この部分の次からint型をchar型にして、System.out.printで表示させたい のですが、小文字のaにはならず61となってしまいうまく表示されません。 どうすれば、aと表示させることができるのでしょうか。 参考書も見ましたが、ぴったりのものも見つからずに八方塞でした。 御分かりになられる方は、ぜひとも御教授していただければとおもいます。 よろしくお願いします。

    • ベストアンサー
    • Java
  • mysql_fetch_arrayでレコードが入っていないものも取得したい。

    こんにちは。mysql_fetch_array()でテーブルに入っていないレコードも取得したいのですが、どのようにすればよろしいでしょうか。 テーブルはこんな感じです。 仕事 NUM  1   1  2   1  4   1  5   1 その上で、PHPはこのようになっています。 //データの選択 $sql = "SELECT job, COUNT(*) as num FROM org GROUP BY job"; $res = db_query($sql, $conn); //データの出力 while ($row = mysql_fetch_array($res, MYSQL_ASSOC)) { $array = array( "job"=>$row["job"], "num"=>$row["num"] ); array_push($array, array( "job"=>$row["job"], "num"=>$row["num"] )); $tmp[] = $array; } return $tmp; このPHPのあと、Smartyに値を渡し、.tplで「A職(○件)」というようなことをやっています。 このときにフィールド「仕事」のレコード「3」は1つもデータが登録されていない状態です。そのためか、現状ではNULL値として扱われるようで、配列$rowに値を渡せず、.tplのほうではデータが表示されません。そこで、レコード「3」にデータを登録せずに、NULL値ではなく、例えば0などの値を渡したいと思います。 どのようなコードを書けば値を渡せるのでしょうか。よろしくお願いします。

    • 締切済み
    • PHP
  • テキストファイルのデータからバイナリを作りたい

    現在、テキストデータとしてCSVファイル1つあたり8バイトのデータが1000個ほどのデータが書かれているファイルがあります。このデータをバイナリファイルへ数値も変換して行きたいと思っています。 たとえば1個目のデータ”12345678”というテキストデータをバイナリの"12345678"に変換したらそれを0x00番地に並べて、そして2個目のデータ”87654321”というデータをバイナリにしたらそれを0x90離れた場所に置いていき、それを1000回繰り返して、結果をバイナリファイルで出力したいのですが、何か簡単にできるフリーソフトなどありませんでしょうか? また、プログラムとかでも簡単にできるのならそうしたいのですが、どうしたらよいか教えていただけないでしょうか?

  • Bシェルのawkコマンドについて

    Bシェルのawkコマンドについてですが、例えばプロンプトから % ls -l hoge.txt | awk '{print $5}' と入力すると、hoge.txtのファイルサイズが出力されますが、同様のことをBシェルの中で行おうと思っています。 下記のように、配列arrayにはスペース区切りで3つのデータが入っており、N番目のデータを取得したいという場合に、Nに変数を使用して取得する方法がわかりません。 #!/bin/sh array="AA BB CC" num=3 # CCを取得したい echo $array | awk '{print $num}' 上記で実行すると、"AA BB CC"のようにすべて出力されてしまいます。awkで出力する箇所を${数値}で指定すればうまくいくのですが、ランダムで決めた数値(1~3)をnumに入れて取得したい場合、このようなことは可能でしょうか。 もし不可能な場合でも、awk以外に何かコマンドがあればご教授願います。なお、作成するのはBシェルになります。

  • データの値の近いものをグルーピングする方法について

    以下アルゴリズムについて考えております。 複数のデータの内、差が±1以内のものをグループ分けする。 ただし、複数の候補がある場合は値の近い方をグループとする。 また、差がまったく同じであった場合は番号の若いほうのグループとする。 例1 ・入力 data1=1 data2=1.5 data3=2 data4=5 data5=6 ・出力 グループ1:1,2,3 グループ2:4,5 例2 ・入力 data1=1 data2=1.3 data3=2.3 data4=5 data5=6 ・出力 グループ1:1,2 グループ3:3 グループ2:4,5 例3 ・入力 data1=1 data2=2 data3=3 data4=4 data5=6 ・出力 グループ1:1,2 グループ2:3,4 グループ3:5 このような結果が得られるプログラムを作成中です。 簡単なグループ分けならできるのですが、候補が複数でてきてしまう場合におかしく なってしまいます。 以下に書いてあるものが初めに思いついた方法の概要です。 このプログラムでは適切なグループ分けが出来ませんでした。 現在はデータの差が±1以内ならばフラグを立てて後でグループ分けをするといった 方法でやっておりますがどうも上手くいきません。 そのため、今回のプログラムについて教えて頂きたく質問をさせて頂きました。 よろしくお願いします。 以下、初めに思いついた方法の概要です。 double in_data[] //データの値 double data[][] //データの差 group[]//グループ番号    //例えばgroup[3]=2だったら、データ3はグループ2に入る //data1-data2 //data1-data3 //・・・ //と計算をしていくforループ for(n=0; n<=i; n++){   for(m=n+1; m<i ;m++){     data[n][m]=fabs(in_data[n]-in_data[m]);     if(data[n][m]<=1){       group[n]= num;  //グループ番号振り分け       group[m]= num;       num++;     }   } }

  • シリアル通信プログラミングでのバイナリデータ送信

    UNIX系環境(IRIX)でのシリアル通信プログラムを作成していて、 バイナリデータの送信方法がわからず困っています。 write関数を使い、テキストデータの送信は出来ます。 write(fd,"テキスト",byte)のように。 ただ、今回はバイナリデータ送信を考えており、 例えば1byteのデータ00000001(01H)を送りたいと思っています。 このデータを送る場合、write関数で実現出来るのでしょうか? write(fd,0x01,1)←イメージです。 色々ネットで調べても出てきません。 開発がWindows環境ではないので、API関数が使えない状況で困っています(MsComm等が使えない)。また、fwrite関数は使用してはいけないみたいです。教えてください。宜しくお願いします。