バイナリファイルにデータを書き込むプログラムを作りたいと思っています。実は、Standard MIDI Fileのバイナリファイルを作りたいんです。
SMFについては、今まで、直接バイナリエディタで開き、16進数の数字をいじくって、データ書き換えたりしてたので直接バイナリファイルに16進数での数字を書きたいんです。
たとえば、テキストファイルに903C408360803C0000みたいに吐き出すプログラムでは、バイナリファイルに書き出してからバイナリエディタで開くと
こいつがさらに16進数に変換されてしまいますよね?
そうならないようにするにはどうやればいいんですか?

このQ&Aに関連する最新のQ&A

A 回答 (5件)

こんにちは。

itohhといいます。

>このプログラムでは、903C408360803C0000のみを出力してますよね。
これは、あくまでも例ですから...

実際は、どのようなバイナリデータを設定したいのかによってmemcpyになるか、あるいは
その他の設定方法になるかは、yabuchanchanさんのプログラムによって変わってきます。

場合によっては、この関数(fncXtoA)を使わずに2文字(1バイト)づつ設定していくほうが
効率がいいかもしれませんし、いくつかのパターンがあるだけで条件によってバイナリデータ
を替えるだけならば、if文などでmemcpyを選択しても良いと思います。

yabuchanchanさんのプログラムにあった方法にこのサンプルを加工して使ってください。
    • good
    • 0
この回答へのお礼

配列を用意してそこに2文字ずつ入れて行きました。
そうするとうまくいきました。
毎回いろいろな事教えて頂いてありがとうございます。
また、わからないことあったらよろしくお願いいたします。

お礼日時:2001/12/05 09:12

こんにちは。

itohhといいます。

>0x90と書き出せばそれは、もしテキストファイルで開けると、
>文字化けしてしまうということなんですか?
ACSII文字コードというのをご存じですか?
”0”文字->16進数では30となります。
”9”文字->16進数では39となります。
”A”文字->16進数では41となります。
”F”文字->16進数では46となります。

ですから、0x90は文字としては”・”と表示されてしまうんです。
バイナリエディタで表示すると0x90と表示されるはずです。
バイナリで出力するということはそういうことです。

サンプルを下記に載せておきます。参考にしてください。
判らないところがあれば補足してください。
ただし、当方、Windowsですので、Mac特有のことはアドバイスできません。
(インデントするために行の先頭に全角スペースを入れています。)
#include <memory.h>
#include <stdio.h>

int fncXtoA(char *des, char *Hex )
{
  int i=0;
  char buf=0x00;
  
  /* 2文字分を1バイトに変換する。 */
  for( i=0; i<2; i++)
  {
    /* 4ビット左にシフトさせる */
    buf <<= i*4;

    if(des[i] >= '0' && des[i] <= '9' )
    {
      buf += des[i] & 0x0f;
    }
    else if(des[i] >= 'A' && des[i] <= 'F')
    {
      buf += des[i] - 0x37;
    }
  }
  
  memcpy( Hex, &buf, 1 );
  
  return 0;
}


int main()
{
  char wBuf[100];
  char wItem[100];
  int i=0;
  int j=0;
  int Count=0;
  FILE *fout;
  int num=0;
  
  memset( wBuf, 0x00, sizeof(wBuf) );
  memset( wItem, 0x00, sizeof(wItem) );
  memcpy( wItem,"903C408360803C0000", 18 );
  
  /* wItem内の文字列分ループする */
  for(i=0; wItem[i] != 0x00; i+=2,j++ )
  {
    fncXtoA( &wItem[i], &wBuf[j] );
    Count++;
  }
  
  /* ファイルにバイナリ出力する */
  if( (fout = fopen( "test.out", "w+b" )) != NULL )
  {
    num = fwrite( wBuf, sizeof( char ), Count, fout );
    fclose( fout );
  }
  
  return 0;
}

この回答への補足

こんにちは。
このプログラムでは、903C408360803C0000のみを出力してますよね。
ここに、条件によって違うものを出力させたいんですけど、その時に
条件文はどのようにこのプログラムに合体させたらいいのかが、よく
分かんないです。
やっぱり、memcpyをいじるんですか?

補足日時:2001/12/03 12:14
    • good
    • 1

itohh氏の回答へのお礼をみていて思ったのですが…



コレ、「90」の十六進数をテキストに出力したいんじゃなくて
書き出したファイルをバイナリエディタで開いたときに
1バイト目の値が「90」になるように書き出したいんではないですか?

で、そう仮定して書きます。
よく知らないので自信がありませんが、こういうときは
"stdio.h"内のfwrite関数かと思います。
書式はfwrite(const void* buf, size_t size, size_t n, FILE* fo);
でbufの内容をsizeバイトずつn個、foで開いたファイルに書き出します。

これで、このときbufに903C408360803C0000(十六進数で一バイトずつ)を
書き込んでおけば、狙ったとおりに出力されるんではないかと。

もっと効率のいい書き方がありそうですが…

この回答への補足

>コレ、「90」の十六進数をテキストに出力したいんじゃなくて
>書き出したファイルをバイナリエディタで開いたときに
>1バイト目の値が「90」になるように書き出したいんではないですか?

そうです。
fwrite関数で書いても変になったので・・・。
bufというのをつかうんですね?いまいちこのbufの使い方をわかってないんで・・・・。
ちょっと勉強してみます!
ありがとうございました!!!

補足日時:2001/11/27 21:15
    • good
    • 0

こんにちは。

itohhといいます。

使用しているOS、開発環境がなにか判らないのではっきりしたアドバイスができませんが
考え方として。

>テキストファイルに903C408360803C0000みたいに吐き出すプログラム
これは、英数字を文字列として書き出しているということですよね?
バイナリとしたい場合は、例えば。
先頭の"90"を例にすると、
文字列"90"ではなく、16進数「0x90」(C,C++の場合)として書き出さなければいけません。

ですから、プログラム内で何らかの変換が必要だということです。
    • good
    • 0
この回答へのお礼

言語はC、C++です。
0x90と書き出せばそれは、もしテキストファイルで開けると、文字化けしてしまうということなんですか?

お礼日時:2001/11/27 17:53

言語は?

この回答への補足

言語はC、C++で環境はMacでCodeWarriorです。

補足日時:2001/11/27 17:50
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qバッチファイルからバッチファイルを呼びだす

例えば「テスト.bat」というバッチファイルを開こうとして、startやcallコマンドを使っても
「'テスト.bat' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」
と表示されます・・・
書式はいろいろ試しました。
テスト.bat
call テスト.bat
start テスト.bat
call :テスト.bat
call :テスト
などです・・・
どなたか教えてください・・・
あと、画像を呼び出す書式もおまけで教えてくれたらうれしいです!

Aベストアンサー

現在作業中のフォルダ(カレントディレクトリ)を確認してみてください。

エラーが出る一文の前に、以下の一文を追加すると、カレントディレクトリが表示されます。

CD
pause

カレントディレクトリが分かったら、そこに呼び出すバッチファイルがあるか確認してください。

又、メインのバッチファイルと同じ場所に「テスト.bat」があるのなら、「call "%~dp0テスト.bat"」と記述しても良いです。

「%~dp0」の意味は、
「%0」が「実行中のバッチファイルのフルパス」を表し、
「~dp」は、「その内のドライブレターとパス」という意味です。
最後は「\」で終わります。

つまり、「実行中のバッチファイルがあるフォルダのパス」という意味になります。

カレントディレクトリは、特にそのバッチファイルに対し何かのファイルをドラッグ&ドロップした場合に注意が必要です。

カレントディレクトリが、バッチファイルのあるフォルダではなくなる可能性があるからです。

その場合は、「pushd "%~dp0"」等の一文を、バッチファイルの最初の方に書いておくと良いかと思います。

これは、「そのバッチファイルがあるフォルダをカレントディレクトリにする」という一文です。

又、フルパスの中に「%」や「^」等が入っていてもエラーになると思いますので、そこもチェックしてみてください。

現在作業中のフォルダ(カレントディレクトリ)を確認してみてください。

エラーが出る一文の前に、以下の一文を追加すると、カレントディレクトリが表示されます。

CD
pause

カレントディレクトリが分かったら、そこに呼び出すバッチファイルがあるか確認してください。

又、メインのバッチファイルと同じ場所に「テスト.bat」があるのなら、「call "%~dp0テスト.bat"」と記述しても良いです。

「%~dp0」の意味は、
「%0」が「実行中のバッチファイルのフルパス」を表し、
「~dp」は、「その内のドライブレ...続きを読む

Q進数変換のプログラムタイトルの由来

進数変換のプログラムのタイトルでは
dec2bin
dec2hex
bin2dec
bin2hex
hex2bin
hex2dec
などのタイトル名を聞きます
dec(10進),bin(2進),hex(16進)なのは分かるのですが、真ん中の"2"の意味がわかりません。このタイトルの由来を知っている方是非教えてください。

Aベストアンサー

英語の慣用表現で2=toです from dec to bin
forを4 youをuなどと書きます

Qjavaプログラミングにおけるバッチファイル起動

JavaのプログラムからNetbeansを用いてバッチファイルを起動させることを考えています。
以下のようにプログラムを作成したところ、コマンドプロンプトの画面は表示されるのですが、バッチファイルの中身が起動されません。
どのようにしたらよろしいかお知恵を拝借願います。
public class Open_JTalk {

private Process p;

private void start() {
try {
//String command = "cmd.exe /c start";
String command = "cmd.exe /c start lib/open_jtalk/m001_106.bat";
p = Runtime.getRuntime().exec(command);


} catch (Exception e) {
}
}

public static void main(String args[]) {
Open_JTalk jtalk = new Open_JTalk();
jtalk.start();
}
}

バッチファイルを動かすのみの処理で、
String command = "lib/open_jtalk/m001_106.bat";
とした場合は何も処理されずにプログラムが終了してしまいます。

また、バッチファイルはlib/open_jtalk/に配置済みです。
ディレクトリのbatファイルをクリックで動かした場合には正常に起動しています。

どうかよろしくお願いします。

JavaのプログラムからNetbeansを用いてバッチファイルを起動させることを考えています。
以下のようにプログラムを作成したところ、コマンドプロンプトの画面は表示されるのですが、バッチファイルの中身が起動されません。
どのようにしたらよろしいかお知恵を拝借願います。
public class Open_JTalk {

private Process p;

private void start() {
try {
//String command = "cmd.exe /c start";
String command = "cmd.exe /c start lib/open_jtalk/m001_106.bat";...続きを読む

Aベストアンサー

確認してませんが、

String command = "cmd.exe /c start lib\\open_jtalk\\m001_106.bat";
では?

Windowsの標準コマンド(この場合cmd.exe)のコマンドラインでのパス区切りは \ だけです。
APIレベルでは、/ も使えますが。

Q数字、英語以外で直接入力できるコンピュータ言語はあるのでしょうか?

自国語入力するプログラミングソフトはありますが、逆コンパイルというのですか、ソースコードは英語に変換されています。プログラム言語の中でアラビア数字や英語以外の数詞や言語で、そのまま変換なしで打ち込めるプログラミングは存在するのでしょうか?よろしくお願い致します。

Aベストアンサー

もしかして、Mindのようなのでしょうか。

Mindは、英語にせずに直接、日本語をインタープリターで処理しています。
実際は、FORTH+日本語処理といっていいかもしれませんが、FORTHのインタープリター自体が言語非依存(意味論的な処理をしないので)ですから、逆ポーランド記法さえ守ればどの言葉にもポーティング可能です。偶々、日本語が逆ポーランド記法との相性が良かったので、Mindが生まれました。
コンパイラのように中間のアセンブラソースというのは存在しません。

参考URLで試用版がダウンロードできるのでおためしください。

参考URL:http://mindclub.scripts-lab.co.jp/

QDOS バッチファイルコマンド記述について

DOSのバッチファイルを利用してコマンドを記述したバッチファイルを作り、
ドロップしたファイルのバイト数を見て1000バイト以上あったら指定のフォルダに
移動させたいと考えています。素人ながらに以下のファイルを作ってみたのですが
うまく動いてくれません。添削して頂けると助かります。よろしくお願いします。

:start
if %1""=="" goto end
if "%~z1" gtr 1000 move "%1" C:\bk
shift
goto start
:end

Aベストアンサー

これでいかがでしょうか。
ファイルをD&Dする場合にディレクトリ名に空白があると""でくくられて渡されるので、%~1を使っています。ただしディレクトリ名に全角空白があるとうまくいかない場合があります。

:start
if "%~1"=="" goto end
if %~z1 gtr 1000 move "%~1" C:\bk
shift
goto start
:end

Qshellで16桁の数字が含まれるファイルをリストアップするという処理

shellで16桁の数字が含まれるファイルをリストアップするという処理を作ろうとしています。
システムの全ファイルを対象にするので、短時間で処理を終えたいです。
アイデアだけでも良いのでお力添え宜しくお願い致します。
動作環境はUNIXです。

Aベストアンサー

「含まれる」のがファイル内かファイル名かが不明ですが、ファイル名なら

find / -type f | grep \d{16}

で、ファイル内なら

find / -type f -exec grep -l \d{16} {} \;

とか。
#試してないので動作は保障しませんが

QDOSバッチ処理でファイル名の取得

選択した複数のファイルの名称を取得する目的で、以下の内容のバッチファイルを作成し、(右クリック>送る) で使えるようにしています。
選択するファイル名が少なければ問題なく.txtが作成されるのですが、ファイル数が100を超えると(選択したファイルによって上限が変わる).txtが作成されなくなります。
バッチファイルの内容に問題があるのでしょうか?
アドバイスをお願いします。

:start
if "%~1"=="" goto end

dir /b %1 >> %TEMP%\List.txt

shift
goto start

:end

Aベストアンサー

バッチファイルというのは、実際には、cmd.exe というプログラムが処理の主体です。
そして、右クリックで「送る」とした場合、最終的には、 cmd.exe file1 file2 .... という文が生成されて、これが実行されます。

で、cmd.exe が受け取れる文字数には、上限があります。(おそらく、8196文字)

http://support.microsoft.com/kb/830473/ja

で、この文字列を超えると、それ以降のファイル名が切り捨てられてしまうのだろうと思います。

QPIC16F88で500という数字を8ビット+2ビットのレジスタに設定

PIC16F88で500という数字を8ビット+2ビットのレジスタに設定する方法を教えていただきたいです。

変数D1,D2,D3にそれぞれ、0,0,5 という500を意味する各桁の数字が入っているのですが、
これをPWMのDutyのレジスタに8ビット+2ビットで設定したいのですが、
どんな手順をとったら10ビットの2進数に変換できるでしょうか?

Aベストアンサー

16bit単位アクセス可能なレジスタなら普通にshort型変数にD1~D3を合成した結果を入れた上で、その変数を直接レジスタに投げ込めば問題なく入ります。

8bit単位でアクセスするなら、このshort型変数を上位バイト・下位バイトに分割(ビット演算とビットシフトでできます)してそれぞれ投げればOK。

2bit側の残り6bit(以上)の部分に何かしらの意味がある場合はその部分を保持して合成する手順が入るので少し面倒ですが、単純には上記の考え方がベースになります。

Qバッチファイルについて

バッチファイルを作成して、スカイプとMSNメッセンジャーの同時起動はできるのですが、そのあとに「C:\Windows\system32\cmd.exe」というコマンドプロンプトの画面が3つ出てしまうのですが、これはアプリ起動の後に自動的に消せないものなのでしょうか?教えてください。

(作成したバッチファイル)
start
CD C:\PROGRA~1\Skype\Phone
skype.exe
start
CD C:\PROGRA~1\"Windows Live"\Messenger
msnmsgr.exe
exit;

skype.exeの前にexit;と書いた場合、MSNが起動しませんでした。

Aベストアンサー

以下をbat内に記述して実行して下さい。
Vistaはx64版しか持っていないのでx86版の場合のフォルダ構造は把握していません。
適宜訂正して下さい。
空白はTabではなくスペースキーです。

@echo off
start "" "C:\Program Files (x86)\Skype\Phone\Skype.exe"
start "" "C:\Program Files (x86)\Windows Live\Messenger\msnmsgr.exe"
exit

QPIC 16F84A のプログラム

①MOVLW 01H と
②MOVLW 9 というのは
どのように動作が違うのでしょうか?
①はWレジスタに16進数"01"をセットするということだと思うのですが
②もWレジスタに10進数"9"をセットするということなのですか?

Aベストアンサー

PICは手がけたことが無いので一般論ですが
レジスタに値が入った時点では、それは数値になるので
値を16進数で表記しようが、10進数で表記しようが何ら関係ありません。
では、なぜ値を16進数で表記したり、10進数で表記したりするのか?
それは人間に対して判り易くするためです。
例えば、
値が個数を表しているなら10進数で表記したほうが判り易い。
値がポートの出力パターンを表しているなら16進数(欲を言えば2進数)で表記したほうが判り易い。
それだけです。


人気Q&Aランキング