「機械語」の版間の差分

削除された内容 追加された内容
318 行
 
=== テキストファイルにある16進ダンプファイルを機械語にしたい場合 ===
==== 概要 ====
たとえばテキストファイル "bintest1.txt" に
9A B3 72
378 ⟶ 379行目:
9A B3 72
 
:※ 上記コードは、分かりやすさを重視して、あえてfor文などのループ機能を用いていないです。実際のソフトウェア作成の際には、for文で実装する事になると思います。
 
上記のプログラミングのコツとしては、<code>char hairetu[1]; </code> のように1要素だけの配列を作ることです。3ブロック読み取りたいのでついつい<code>hairetu[3]</code>とかしてしまうがちですが、それだと、おそらくプログラミングに失敗します。
 
385 ⟶ 386行目:
strtol とは単に、読み取った数字を、読み取りのの際についでに16進数や10進数などの数値変数に変換してくれる、c言語の便利な関数です。
 
 
{{substub}}
 
==== 実用例 ====
fscanf は、読み取り位置が最後まで来ても、そのままでは、最後の文字を何度でも読み取れてしまいます。
 
なので、もし読み取り位置が最後まで来たら、その直後の段階で、書き込み処理を終了する必要があります。
 
この書き込み終了判断の実装のために必要な機能は、fscanfの返却値です。
 
 
fscanfは、もし最後のブロックに来た後に、もう一度fscanf を使うと、返却値として -1 を返します。なおwindowsの場合、最後のブロック以外では(プラスの)「1」を返します。
なので、もし返却値が-1なら、書き込みを終了する処理を実装すればいいのです。
 
 
よってコードは、下記のようになります。
 
;コード例
<source lang=c>
#include <stdio.h>
#include <stdlib.h> // atoi
 
 
int saigoKensa ; // scanfの返却値を格納するための変数
 
int main() {
FILE *file;
char hairetu[1];
 
FILE *fp1;
char str1[150];
 
fp1 = fopen("bintest1.txt", "r");
 
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == -1){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ;
 
int kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
 
file = fopen("test2.bin", "wb");
if (file == NULL) {
printf("ファイルを書き込めませんでした");
 
return 0;
}
 
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
 
 
// 2ブロック目を読むため繰り返す
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == -1){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ; // テスト用
kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
// 読みたい文字のぶんだけ繰り返す
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == -1){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ;
kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == -1){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ;
 
fscanf(fp1, "%s", str1);
kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
 
fclose(file);
return 0;
}
</source>
 
 
==== EOFを用いた例 ====
終了の -1 の代わりに、宣言なしで「EOF」と書いても、コードが正常にコンパイルおよび実行可能です。 なお EOF とは end of file の略です。
 
;EOFを用いたコード例
<source lang=c>
#include <stdio.h>
#include <stdlib.h> // atoi
 
 
int saigoKensa ;
 
int main() {
FILE *file;
char hairetu[1];
 
FILE *fp1;
char str1[150];
printf("EOF is %d \n",EOF) ;
 
fp1 = fopen("bintest1.txt", "r");
 
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == EOF){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ;
 
int kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
 
file = fopen("test2.bin", "wb");
if (file == NULL) {
printf("ファイルを書き込めませんでした");
 
return 0;
}
 
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
 
 
// 2ブロック目を読むため繰り返す
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == EOF){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ;
kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
// 読みたい文字のぶんだけ繰り返す
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == EOF){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ;
kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
saigoKensa = fscanf(fp1, "%s", str1);
if (saigoKensa == EOF){fclose(file); return 0;}
printf("いま返却値は %d \n",saigoKensa) ;
 
fscanf(fp1, "%s", str1);
kazu = strtol(str1, NULL, 16);
hairetu[0] = kazu;
fwrite(hairetu, sizeof(char), sizeof(hairetu) / sizeof(hairetu[0]), file);
 
 
fclose(file);
return 0;
}
</source>
 
実行結果は前述とほぼ同じなので、省略します。
 
上記コードの場合、EOFは <code>if (saigoKensa == EOF)</code> のように、if文の中で使われています。
 
{{stub}}