ページへ戻る

+ Links

− Comments

 印刷 

hideyosi​/hijk​/ファイル入出力 :: OSASK計画

osaskwiki:hideyosi/hijk/ファイル入出力

.g01のファイル入出力 anchor.png

解説読んだけど、どーもわからないのでもう面倒なので体当たりで実験してみっべぇってなページw

cpycのソースを参考に。

Page Top

cpycの検証 anchor.png

これがソース。

#include <guigui01.h>

void G01Main()
{
	static unsigned char cmdlin[] = {
		0x86, 0x50, 0x8a, 0x8c, 0x40
	};
	int i, j;

	g01_setcmdlin(cmdlin);
	g01_getcmdlin_fopen_s_3_5(1);
	for (j = 0;; j++) {
		if (g01_getcmdlin_fopen_m_0_4(0, j) == 0)
			break;
		do {
			i = jg01_fread1_4(2 * 1024 * 1024, g01_bss1a1);
			jg01_fwrite1f_5(i, g01_bss1a1);
		} while (i != 0);
	}
	return;
}

・・・どうも、ファイルのオープンとコマンドラインはセットになってるようだぞ???

うーん。これはちょっと後回し。とにかく、決まりきったファイルをオープンしてみたいな。

Page Top

決まりきったファイルを開いてみる anchor.png

こんなファイルを用意。名前はtest.txt

arusyuno kan yo!
kokorono hirameki yo.
onnnanoko ni ha
nanntonaku wakarunoyo!

ここによると、こんなコードになるのかな・・・

#include <guigui01.h>
void G01Main()
{
      int mode; mode = 1;
//          いっけね・・・Cでは2進数表記ないんだっけ。
//                             00000000000000000000000000000001
//         ???                 00             0          001
//                           書かないので     書かない   とりあえず1                     
      int slot = 4;
//          スロットってなんだべか?あらかじめ用意されたファイルハンドルってことでいい?
      int pathlen = 8;
//          パスの長さってことでいいのかな。test.txtだから、8でいいのかな。

      static unsigned char path[] = { 't','e','s','t','.','t','x','t' };
//          パス。カレントにあるのでファイル名だけでいいはず・・・

      jg01_fopen(mode, slot, pathlen, path); 
//           ファイルをオープンしてみる

      if( slot == -1 ) {
              g01_putc('x') ;
              return;
       }

       g01_putc('O') ;
       return;
//     スロットが-1なら失敗。x(バツ)を表示して終了。そうでなければOを表示
}

なーーーんでだよクッソぉ! jg01_fopenが使えないとか言われるぞ??

ヘンダナァ・・・guigui01.h見ると、jg01_fopenはちゃんとあるんだけど、引数が3つしかないぞ?pathlenが廃止された???

うーん・・・pathlenを引っこ抜いたらとりあえずコンパイルは通ったけど、オープンに失敗するなぁ・・・

pathlenが廃止された? ってことは、パス文字列に終端が必要なのかなってんで、お尻に0を置いてみたけど変わらないなぁ・・・

がーーん! ウッチャンがアドバイスくれた! そうだよ! 大勘違いしてた!!!!!

よーし! とりあえず O が表示されたぞおぉぉ! ウッチャン大感謝! (まーだポインタが怪しいとは。オイラってばもう!)

Page Top

読めるかな?? anchor.png

うーん。jg01_freadなんだが、これも引数が変更されているっぽいなぁ。guigui01.hに従おう・・・

jg01_fread1(int s, int n, void *b) こういう構文だが、先頭のsはスロットらしいので4でいいか。第二引数と第三引数はなんだろ??これ???

げげげ! ↑のcpycのソースでは、なんか違う関数使ってる上に引数が2個・・・それに戻り値があるぞ? なんだべこれ???

Page Top

わーかってきたぞぉぉwww anchor.png

ここに詳しく書いてあった~♪

  • まずは、g01_bss1a1。
    • これはいわばmallocの簡易版みたいな位置づけらしい。とにかくこれを書けば、2MBのメモリをくれるというわけ。
    • なので、別にこれを使わずにmallocを使ってもかまわないはず。たぶん2MB確保とかって頻度が高いのでお便利命令的に搭載されてるんだろう。
  • 次。jg01_fread0_4(2 * 1024 * 1024, バッファ);
    • これも同じくお便利命令と解釈できる。jg01_fread0 でピンで読んでも別にかまわないが、ファイル一個を開くなんてパターンが多いので大抵スロット4が使われる。なので、スロット4を一発で読むっていう命令。第一引数には最大読み込み量を指定するのだろう。とにかくこうしておけば、上限を2MBとしてバッファに内容を読み込み、バッファの終端に0とひっつけてくれると。

さてそんなわけで。こういう風に改良してと・・・

#include <guigui01.h>
void G01Main()
{
  int mode; mode = 1;
//         ???                 00             0          001
//                           書かないので     書かない   とりあえず1                     
      int slot = 4;
//          スロットってなんだべか?あらかじめ用意されたファイルハンドルってことでいい?
      char *path; path = "test.txt"; 
//          パス。カレントにあるのでファイル名だけでいいはず・・・

      jg01_fopen(mode, slot,  path);
//           ファイルをオープンしてみる

      if( slot == -1 ) {
              g01_putc('x') ;
              return;
       }

      char *buffer = g01_bss1a1;
//            2Mのバッファを確保してと・・・     
      jg01_fread0_4(2 * 1024 * 1024, buffer);   /* 2*1024*1024でちょうど2MB */
//            バッファが2MBなので、上限2MBで読み込んでおくれ!
      g01_putstr0(buffer);
//            バッファの内容を文字列として表示してみて!
    g01_putc('O') ;
       return;
}

うおぉぉ!! きたぞぉぉ!!!! よーし! 任せたぞアンジェ!!!

Page Top

エラー処理 anchor.png

ちなみに、上の、ファイルが開けなかった場合の処理は大間違いでございまする・・・orz・・・

うーん・・・fopenの段階での「ファイル開けなかったよ!」って場合の処理がわからんなぁ。もしかして、意図的に省いている??

jg01_freadには二種類あって、末尾に0が付くか1が付くかで性質が変化するのでこれで判定するのかな???

  • jg01_fread0系
    • 読み込んだものを文字列的にあつかう。戻り値がないので書くとエラーになる。
    • 読み込んだデータのオケツに0(文字列終端判定コード?)を自動で付けてくれる。
    • たとえば1000のバッファを用意。読み込んだら、「neko」だけしかないファイルだった。(4文字しか必要ない)
    • バッファ全体は相変わらず1000あるが、内部では、 'n','e','k','o',0x00,・・・ こういう状態になる。
    • なので、普通にg01_putstr0すれば「neko」だけ表示し、5バイト目で終わりだと判断して終了する・・・と。こゆわけ!
  • jg01_fread1系
    • 読み込んだものを文字として扱わない。いうなれば、そのまんまのバイナリで扱う感じ。
    • このため読んだデータなのか、元々バッファに入ってたデータなのかが区別できないので、戻り値を持っている。
    • 戻り値に読み込んだデータのバイト数が入る。
    • 「読んだデータだけを取り出したい」って場合は、自分でバイト数を元にバッファから大きさを指定して取り出さないとデータが狂うことになる
Page Top

書いてみよう! anchor.png

読めたんだから書いてもみようってなもんで!

まず、当然だが、ファイルをオープンしないといけない。書けるようにファイルを開けるには・・・

     int mode; mode = 1;
//          いっけね・・・Cでは2進数表記ないんだっけ。
//                             00000000000000000000000000011001
//         ???                  1               1        001
//                           新規モード?     書くよ  とりあえず1        

これでオープンしてあげればいいと!

そんでもって書いてみる。・・・例によってguigui01.hとニラメっこ・・・なるほどなるほど・・・・

    mode = 0x19;
    slot = 5;
    path = "newfile.txt";
    char *hiyohiyo; hiyohiyo = "hiyokogumo! hiyohiyo ho---!";
//          いっけね・・・Cでは2進数表記ないんだっけ。
//                             00000000000000000000000000011001
//         ???                  1               1        001
//                           新規モード?     書くよ  とりあえず1      

    jg01_fopen(mode, slot,  path);
    jg01_fwrite0f_5(hiyohiyo);

これでメイクして走らせて・・・・って! 書けた!!!

うおぉぉぉ!!! パコかわゆす 書き込めたぞおぉぉ!!!


一般用コメント一覧

  • ちょっと気付いたこと。 jg01_fopen(mode, slot, pathlen, *path); って書いてあるけど、*pathはまずいですよ。pathが"test.txt"が置いてあるメモリの先頭アドレスを表すので、そこに*を付けて*pathにすると、結局先頭1文字を表すchar型になっちゃいます。んで、それを無理やりcharへのポインタだと思い込んじゃって、tのアスキーコードつまり0x74番地にファイル名が置いてあると解釈してしまっていると思われます。  --  uchan   2010/2/1 22:37
一般用コメント欄は使用できません

Last-modified: 2010-02-02 (火) 00:00:00 (JST) (319d) by lina