• ベストアンサー

Stirlingについて

バイナリファイルに16ビットで表現された正数が順番に格納されています. もし(10進数で)1,10,15の値がこの順番で格納されていたら, Stirlingではどのように表示されるのでしょうか? ファイルからこのデータx個を配列dataに読み込むために unsigned short data[x]; fseek(fp, 0L, SEEK_SET); /* ファイルポインタを先頭へ */ fread(data, 2, x, fp); /* 2バイトずつx個読み込む */ としたのですが, このdata[i]に正しく格納されているか確認したいためです. Stirlingで「00 01 00 0A 00 0F」となっていれば,   data[0]:1,data[1]:10,data[2]:15 になると思ったのですが,   data[0]:256,data[1]:2560,data[2]:3840 になりました. ちなみに,256,2560,3840は16進では100,A00,F00です. どこか間違っているのでしょうか? 長くなりましたが,どなたかご教授ください.

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

  • ベストアンサー
  • ntaka
  • ベストアンサー率33% (1/3)
回答No.2

> data[0]:1,data[1]:10,data[2]:15 > になるはずが,なぜ > data[0]:256,data[1]:2560,data[2]:3840になってしまうのでしょうか? data[0]:256,data[1]:2560,data[2]:3840 256,2560,3840は16進では100,A00,F00 ということですから先頭に0を付加すると 0100,0A00,0F00 となります。(2バイト X 3文字 = 6バイト) これをファイルに記録すると Stirlingで見たとおり 「00 01 00 0A 00 0F」と保存されるのです。(2バイトの上位/下位が入れ替わる) これは MS-DOS/Windows系の仕様なのでしょう。MAC-OSは違ったと思います。 分かりにくいけど歴史といきさつがあったのでしょうね。 Stirling、使ったことがありませんが良さそうなのでこの機会に使ってみます。ありがとうございました

landmes
質問者

お礼

回答ありがとうございます. では,data[0]:1,data[1]:10,data[2]:15にするためには, 「01 00 0A 00 0F 00」とすればよいわけですね?

landmes
質問者

補足

16ビット正数が順番に格納されている場合, このデータを取り出すためのプログラムは fread(data, 2, x, fp); で合っているのでしょうか? またファイルの中身をStirlingで編集するときは, 2バイトの上位と下位を入れ替えて書き込まなければならないということでしょうか?

その他の回答 (3)

  • ntaka
  • ベストアンサー率33% (1/3)
回答No.4

下記のご質問については、すべて「はい」だと思います。 余談ですが、2560や0A00と表記したとき左側が上位桁ですよね? エディタでは左側に若いアドレス(のデータ)を表示します。 そのデータが16進2桁なのでその2桁は左側が上位桁になります。 だから、あんまり不思議はないのかも・・ (若いアドレスに下位桁がくるので) > 16ビット正数が順番に格納されている場合, > このデータを取り出すためのプログラムは > fread(data, 2, x, fp); > で合っているのでしょうか? > またファイルの中身をStirlingで編集するときは, > 2バイトの上位と下位を入れ替えて書き込まなければならないということでしょうか? > では,data[0]:1,data[1]:10,data[2]:15にするためには, > 「01 00 0A 00 0F 00」とすればよいわけですね?

landmes
質問者

お礼

おかげさまで分からなかったことがすべて解決できました. ありがとうございました.

  • Werner
  • ベストアンサー率53% (395/735)
回答No.3

リトルエンディアンでは下位バイトが若いアドレスに来ます。 エンディアン - Wikipedia http://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3 エンディアンはOSというよりもプロセッサに依存します。

landmes
質問者

お礼

回答ありがとうございます.

  • ntaka
  • ベストアンサー率33% (1/3)
回答No.1

どこにも間違いはないと思います。 ファイルには unsigned short の下位バイト、上位バイトの順で 保存されるのでそうなると思います。

landmes
質問者

お礼

回答ありがとうございます. data[0]:1,data[1]:10,data[2]:15 になるはずが,なぜ data[0]:256,data[1]:2560,data[2]:3840になってしまうのでしょうか?

関連するQ&A

  • バイナリエディタのビットイメージを出力したい

    ***.DATファイルをバイナリエディタで開いてビットイメージで見るとあきらかに画像っぽいデータを発見したので、そのデータをファイルとして出力するにはどうすればいいのでしょうか? 調べたところ、 // imageデータ出力 for (line_cnt = height - 1; line_cnt >= 0; line_cnt--){ fseek(fp_rom, data_baseaddr + line_cnt*width, SEEK_SET); for (pixel_cnt = 0; pixel_cnt < width; pixel_cnt++){ fread(&datatmp, 1, 1, fp_rom); fwrite(&datatmp, 1, 1, fp_bmp); } } fseek(fp_rom, data_baseaddr + datasize, SEEK_SET); こんな感じらしいのですが これをどうすればいいのでしょうか?

  • VisualC++でのバイナリファイル

    VisualC++でのバイナリファイルのサイズの取得。 Win7 x64 VC++2012 調べた所によると、 バイナリモードではNULL文字を使用できるため、 FILE* fp; fopen_s(&fp,"data.bin","rb"); fseek(fp,0,SEEK_END); size_t fsize=ftell(fp_cl); //fseek(fp,0L,SEEK_SET);//元の位置に戻す。 fclose( fp ); のような感じでサイズを取得してはいけない。 (fseekのSEEK_END動作が不定のため) ……と思っていたのですが、他に方法と言えば、 ファイルを一度全て空読みするくらいしかないので、 試にやってみたところ、上手く行ってしまいます。 一応NULLの入ったバイナリでも正しく取得できてしまいました。 これはCの仕様が変わったためなのか、VC++がたまたま対応しているのか、 どちらでしょうか? また、他に上手い方法があればよろしくお願いいたします。

  • 2次元配列への格納方法について

    こんにちは。 FILE *fp; SIZE 1024; int n; char Buf[1025]; while((n = fread(Buf,1,SIZE,fp)) != 0){ } というように、fread関数を用いて1024バイトずつ配列Bufへ格納しています。 以下に示すようなことを行う場合、どのように記述すればよいのでしょうか? B:バイナリデータ T:数値 TBBBBBBBBB・・・・・・B←1024バイト目 TBBBBBBBBB・・・・・・B ・ ・ ・ ・ TBBBBBBBBB・・・・・・B というように、配列内に格納したいと思っています。 Tは、テキストデータで1,2,3・・・・100という整数型を格納。Bは、バイナリデータでfread関数から取得したバイナリデータを格納します。 なぜ、Tを格納したいかといいますと、どのバイナリデータを指しているか?を判別するためです。 上記のようなことを行うためには、2次元配列を使用すればよいのでしょうか? 例:char Buffer[100][1025]

  • バイナリで書き込みましたがエラーが出る。原因は?

    拡張子を.wavとしてあるa.wavというファイルがあります。 fopenとfread関数を用いて以下のように読込み、 fp = fopen("a.wav","rb"); fread(data[0],4,1,fp); fopenとfwriteを用いてb.wavファイルに以下のように書き込みました。 fa= fopen("b.wav","wb"); fwrite(data[0],4,1,fa); 書き込んだb.wavファイルですが、 バイナリエディタStirlingでa.wavとb.wavファイルの中身を比較したら中身は同じでした。 しかし、a.wavファイルでは音が出力されるのに、b.wavファイルでは音が出力されずエラーが出ます。 この原因はいったいなんでしょうか? 原因がわかる方がいましたら教えていただけないでしょうか? よろしくお願いいたします。

  • fread()エラー

    お世話になります。 今、バイナリファイルを操作しているのですが、 fread()でエラーになってしまいます。 char buf1[256]; FILE *fp; vector<string> f1; int num; fp = fopen("hoge.txt","r"); while( fgets( buf1, sizeof(buf1),fp ){ f1.push_back( buf1 ); num ++; } fclose(fp); FILE *cfp; unsigned char data[1024]; for(int i=0; i<num; i++ ){ cfp = fopen(f1[i].c_str(), "rb"); fread( data, sizeof(char), 1024, cfp ); } hoge.txtには、コンテンツ場所(パス)が複数記載されており、 その1つずつをfread()で読み込み解析したいのですが、 fread()でセグメンテーション違反になります。 f1の中味をprintf("%s",f1[0].c_str()); で見てみると正常にコンテンツの場所が格納されています。 また、 string pp = "/home/hoge/hoge.txt"; cfp = fopen(pp.c_str(), "rb"); fread(bb,sizeof(char),1024,cfp); とすると正常に動作します。 どうぞよろしくお願い致します。

  • Ç言語でファイルサイズを変更するプログラム

    Ç言語初心者です。visualstudio2010を使用しています。 ファイルサイズ100MBのtest.binをバイナリモードで開き、10GBになるまで0を追加するプログラムを組みたいと思います。 ファイルを読み込んで出力するようには組めたのですが、この手法だとファイルサイズが大きいと時間がかかってしまいます。 現在のソースは以下の様になっているのですが、どうしたらもっと早く終わらせることが出来るでしょうか? また、int型でファイルサイズを取得していますが、ファイルサイズがもっと大きくなったときにint型では足りなくなってしまうのもどうすればいいのか困っています。 ※元ファイルサイズ(test.bin)は例としています。今後?GBサイズになると思います。変更後のファイルサイズは今後10GBくらいまでで考えています。 #include <stdio.h> #include <string.h> #include "stdafx.h" #define KIRO (1024) #define MEGA (KIRO*1024) #define GIGA (MEGA*1024) #define SIZE (100) int main(void) { FILE *fp,*fpw; unsigned char c; unsigned char zero = 0; int i = 0; int filesize; // 元ファイルをバイナリモードで開く fp = fopen( "test.bin", "rb" ); if( fp == NULL ) { printf( "test.binが開けません" ); return 1; } fseek( fp, 0, SEEK_END ); filesize = ftell( fp ); fseek( fp, 0, SEEK_SET ); // 書込み先をバイナリモードで開く fpw = fopen( "test_W.bin", "wb" ); if( fp == NULL ) { printf( "test_W.binが開けません" ); return 1; } while(1) { i++; // 指定サイズになったら終了 if(i > MEGA * SIZE) break; // ファイルサイズまで読み書き if(filesize < i){ // 残りを0で代入 fwrite(&zero, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ }else{ // ファイルの内容を1文字ずつ読み書き fread( &c, sizeof(unsigned char), 1, fp ); /* 1文字ずつ読み込み */ fwrite(&c, sizeof(unsigned char), 1, fpw); /* 1文字ずつ書き込み */ } printf( "%d番目\n", i ); } printf( "\n" ); fclose(fp); fclose(fpw); return 0; }

  • ファイルサイズの取得について

    2つのテキストファイルのサイズを取得し、そのファイルサイズ分だけを動的にメモリを確保しようとしています。 int *c,*a;と宣言し、 fp=fopen("./data/Problem.txt","r");//1つ目のファイル fseek(fp, 0, SEEK_END); /* ファイルの終端までシーク */ size = ftell(fp); /* 終端の位置、すなわちファイルサイズを得る */ fseek(fp, 0, SEEK_SET); /* ファイルの先頭に戻る */ c = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ while((x=fgetc(fp))!=EOF){ c[i]=x; i++; } c[i]='\0'; i=0; fclose(fp); fpa=fopen("./data/Answer.txt","r");//2つ目のファイル fseek(fpa, 0, SEEK_END); size = ftell(fpa); fseek(fpa, 0, SEEK_SET); a = (int *)malloc(size); while((x=fgetc(fpa))!=EOF){ a[n]=x; n++; } a[n]='\0';//・・・・(1) n=0; fclose(fpa); とすると1つ目のファイルの方だけはうまくいくのですが、(1)の部分で 「sample.exeの0x00411dcでハンドルされていない例外が発生しました:0xc0000005:場所0x0000000に書き込み中にアクセス違反が発生しました。。」 というエラーが出ます。 また、 int *c,*a;を int *c,a[300]; のように片方を配列として宣言し、 //a = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ のようにコメントアウトすると上記のエラーは出ずにcにメモリは確保されているようです。 これは何故なのでしょうか? また、どうすればaとcでメモリを確保出来るようになるのでしょうか? よろしくお願いいたします。

  • fseekの使い方

    C言語で、 #include "stdafx.h" #include <stdio.h> void main(void) { FILE *fp; fp = fopen("text.txt", "a+"); fseek(fp, 0L, SEEK_SET); fputs("0\n12345",fp); fseek(fp, 0L, SEEK_SET); fputs("6\n789",fp); fclose(fp); } と書き、text.txtに abcde と書いてあるとします。 私の目論見では、a+で開いている為ファイルの最後から書き始めるとしても、 fseekで最初に戻るので、実行すればtext.txtの中身は 6 78945 になると考えていたのですが、 結果は abcde0 123456 789 となりました。 fseekをいじって-3Lとかにしてみたのですが、fseekによって書き込む位置が動いている様子がありません。 fseekの使い方が間違っているのでしょうか? ちなみに環境はWindowsXPで、Visual C++ 2008で行っています。

  • icon format について

    Visual Studio.NET 2003 MFC を使用しています。 View画面で、アイコンを表示しようと思いました。 アイコン読み込みようのクラスを作成しました。 class icon { public: void IconHeadRead(FILE *fp,int *width,int *height) { unsigned char uc; unsigned short us; unsigned int ui; fread(&us,sizeof(unsigned short),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&uc,sizeof(unsigned char),1,fp);*width=uc; fread(&uc,sizeof(unsigned char),1,fp);*height=uc; fread(&uc,sizeof(unsigned char),1,fp); fread(&uc,sizeof(unsigned char),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&us,sizeof(unsigned short),1,fp); fread(&ui,sizeof(unsigned int),1,fp); }; void IconDataRead(FILE *fp,unsigned char *red,unsigned char *green,unsigned char *blue) { unsigned char uc; fread(&uc,sizeof(unsigned char),1,fp);*red=uc; fread(&uc,sizeof(unsigned char),1,fp);*green=uc; fread(&uc,sizeof(unsigned char),1,fp);*blue=uc; }; }; このred,green,blueの値を使用して、 SetPixelでドローしようと思いましたが、 変な表示になります。 width,heightは、正しいようです。 ICON フォーマットについて教えてください。 よろしくお願いします。 同じような要領で、bitmapは保存、読み込みはできました。

  • 行毎の黒のドット(ピクセル)数を教えていただけませんか?

    開発環境Microsoft Visual Studio .NET 2003 2値画像を読み込んだ時、各行毎の黒のピクセル(ドット)数を表示する プログラムを組もうとしているのですがわかりません。 画像読み込みまではできたのですがその後のプログラムがわかりません 誰か組んでいただけないでしょうか? #include <stdio.h> #include <process.h> #define Y_SIZE 3648 // 処理できる最大画像 #define X_SIZE 3648 #define HIGH 255 // 画像の最大強度値 #define LOW 0 // 画像の最小強度値 #define LEVEL 256 // 画像の強度レベル値 // BMPファイルのフォーマットに従って用意した変数 typedef unsigned short WORD; typedef unsigned long DWORD; WORD bfType; DWORD bfSize; WORD bfReserved1, bfReserved2; DWORD bfOffBits; DWORD biSize, biWidth, biHeight; WORD biPlanes, biBitCount; DWORD biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant; unsigned char image_in[Y_SIZE][X_SIZE][3]; // 入力カラー画像配列 unsigned char image_out[Y_SIZE][X_SIZE][3]; //出力カラー画像配列 unsigned char image_bw[Y_SIZE][X_SIZE]; //濃淡画像配列 unsigned char data_rgb[Y_SIZE][X_SIZE][3]; // RGB画像配列 //******************************************** // 24Bitビットマップファイル読み込み * //******************************************** void readBMP( char *filename, // BMPファイル名 unsigned char image[Y_SIZE][X_SIZE][3] // 24ビットRGB画像配列 ) { FILE *fp; int i, j, k; // ファイルオープン if ((fp = fopen(filename, "rb"))==NULL) { printf("readBmp: Open error!\n"); exit(1); } printf("input file : %s\n", filename); // ヘッダー情報読み込む fread(&bfType, sizeof(bfType), 1, fp); fread(&bfSize, sizeof(bfSize), 1, fp); fread(&bfReserved1, sizeof(bfReserved1), 1, fp); fread(&bfReserved2, sizeof(bfReserved2), 1, fp); fread(&bfOffBits, sizeof(bfOffBits), 1, fp); fread(&biSize, sizeof(biSize), 1, fp); fread(&biWidth, sizeof(biWidth), 1, fp); fread(&biHeight, sizeof(biHeight), 1, fp); fread(&biPlanes, sizeof(biPlanes), 1, fp); fread(&biBitCount, sizeof(biBitCount), 1, fp); fread(&biCompression, sizeof(biCompression), 1, fp); fread(&biSizeImage, sizeof(biSizeImage), 1, fp); fread(&biXPelsPerMeter, sizeof(biXPelsPerMeter), 1, fp); fread(&biYPelsPerMeter, sizeof(biYPelsPerMeter), 1, fp); fread(&biClrUsed, sizeof(biClrUsed), 1, fp); fread(&biClrImportant, sizeof(biClrImportant), 1, fp); // RGB画像データ読み込む for (i=0; i<(int)biHeight; i++) for (j=0; j<(int)biWidth; j++) { for (k=0; k<3; k++) { //fread(&image[i][j][2-k], 1, 1, fp); fread(&image[biHeight-i][j][2-k], 1, 1, fp); } } fclose(fp); } //********************************************** // RGBカラー画像を256諧調白黒濃淡画像へ変換 * //********************************************** void BMPto256BW( unsigned char image[Y_SIZE][X_SIZE][3], unsigned char image_bw[Y_SIZE][X_SIZE] ) { int y, x, a; for (y=0; y<(int)biHeight; y++) for (x=0; x<(int)biWidth; x++) { a = (int)(0.3*image[y][x][0] + 0.59*image[y][x][1] + 0.11*image[y][x][2]); if (a<LOW) a = LOW; if (a>HIGH) a = HIGH; image_bw[y][x] = a; } } //***************************************** //各行の黒色判定 //***************************************** //**************************************** // 白黒濃淡画像配列のコピー * //**************************************** void imageCopyBW( unsigned char image1[Y_SIZE][X_SIZE], unsigned char image2[Y_SIZE][X_SIZE] ) { int x, y; for (y=0; y<(int)biHeight; y++) for (x=0; x<(int)biWidth; x++) image2[y][x] = image1[y][x]; } void main(void) { char input[100], output[100]; int intensity; printf("入力画像ファイル名(*.bmp):"); scanf("%s", input); readBMP(input, image_in); // 画像の入力,RGB24ビットカラーBMP画像を配列に格納 //一列各行の黒色の数出力 }

専門家に質問してみよう