2009-05-07 8 views
2

可変長レコードのバイナリファイルから読み取る:は、私はこのような程度に見える可変長レコードを持つバイナリファイルを持っている

12 economic10 
13 science5 
14 music1 
15 physics9 
16 chemistry9 
17 history2 
18 anatomy7 
19 physiology7 
20 literature3 
21 fiction3 
16 chemistry7 
14 music10 
20 literature1 

もちろんの名前は、最初のファイルでのみ可変長レコードですnumberはコースのコードで、1から9999の間の数字で、2番目の数字は部門です.1から10までの数字を入力できます。 ファイルの中にはコースの名前の間にスペースはありませんおよび部門番号。

質問はどうすればバイナリファイルから読み込むことができますか?ファイルには、コース名である文字列のサイズを教えてくれるフィールドはありません。 最初のint(コースID)を読み込むことはできますが、どのように名前のサイズがわかっていますかコース?

+0

なぜこれがバイナリファイルだと思いますか?あなたはテキストのように見える?記録終了マークは何ですか?または、各レコードの長さはありますか? (可変長レコードでは、どちらか一方、つまりレコードの開始マークが必要です。) –

+0

どのようなプログラミング言語ですか? COBOL? Visual Basic? C++? Python? Lisp? – chmike

+0

@chmike質問のすぐ下にある青色のボックスが表示されますか?最初のものを見てください。 –

答えて

3

fscanf()には、フォーマット文字列"%u %[a-z]%u"を使用してください。

はここで完全なプログラム例です:

#include <stdio.h> 

#define NAME_MAX 64 

int main(int argc, char ** argv) 
{ 
    FILE * file = fopen("foo.txt", "rb"); 
    unsigned int course, department; 
    char name[NAME_MAX]; 

    while(fscanf(file, "%u %[a-z]%u", &course, name, &department) != EOF) 
    { 
     // do stuff with records 
     printf("%u-%u %s\n", department, course, name); 
    } 

    fclose(file); 

    return 0; 
} 
0

可変長レコードを読み取るには、何らかの種類の規則を使用する必要があります。たとえば、レコードの終わりを示す特殊文字です。すべてのレコードの中に、フィールドの終わりを示す別の特殊文字を使用できます。

DO_READ read from file 
      is END_OF_RECORD char present? 
      yes: GOTO DO_PROCESS 
      no : GOTO DO_READ 

DO_PROCESS read into buffer 
      is END_OF_FILE mark present? 
      yes: GOTO DOSOMETHINGWITHIT 
      no: GOTO DO_PROCESS 
+0

[OK]をクリックすると、「\ n」がレコードの末尾になります。すべてのレコードが改行で始まることを意味します。どうすればそれを読むことができますか? –

+0

テキストファイルまたはバイナリファイルについて話していますか?あなたの例はテキストのように見え、レコードの最後に改行を追加すると、テキストのように聞こえます。バイナリ文字列を区切りたい場合は、特にCを使用している場合は、ヌル文字( '\ 0')を使用しないでください。 – KeyserSoze

+0

先生は、バイナリファイルはこのように見えると教えてくれました。実際のバイナリファイルを私たちに渡すことはできません。私たちはそれを読むことができないので、私は本当にすべての記録。私は何とかファイルから何らかの形で各レコードを読む必要があります。非常に奇妙です。私は同意します... –

0

最初にファイルがどのように書き出されたかを知る必要があります。

0

コースコードとコース名(部門コードを含む)の間に1対1の対応がある場合は、コース名のサイズをコードから推測し、コードのどこかの設定ファイル。

私が見ている主な問題は、music1music10のようなものを区別することです。

+0

問題は私がコース名の文字列のサイズが分からないので、どうすればそれを読むことができますか?それは5文字にすることができ、それは20文字にすることができます。私はレコードが "\ n"で終わることを知っています、それは私を助けますか? –

+0

はい!それはあなたを助けます! – Albert

1

他の人は、これはテキストによく似ていると言われているので、テキスト解析のアプローチが正しい方法になる可能性があります。これは宿題ですので、私はあなたのためにそれをコーディングするつもりはないが、ここで私が取ると思います一般的なアプローチです:

  • の関数fscanfを使用して、名前や部署でコースコード、および組み合わせた文字列を読んでコード。
  • 組み合わされた文字列の最後から始めて、最初の数字以外が見つかるまで後方に移動します。これはコース名の終わりです。
  • コース名の末尾を越えて始まる整数(つまり、後方に向かってスキャンされた最後の数字)を読み取ります。
  • 文字列の整数部分の最初の文字をNUL( '\ 0')に置き換えます。これにより、コース名の直後に結合された文字列が終了します。したがって、結合された文字列に残っているのはコース名だけです。コースコードと部門コードが整数変数にあります。
  • 次の行について繰り返します。
0

なしキャリッジリターンがないと仮定すると、各文字列がnullで終了します。 私は、バイナリファイルを作成してそれを読み戻し、同様の出力を生成する小さなプログラムを作成しました。

 

// binaryFile.cpp 
#include "stdafx.h" 
#include <stdio.h> 
#include <string.h> 

#define BUFSIZE 64 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    FILE *f; 
    char buf[BUFSIZE+1]; 

    // create dummy bin file 
    f = fopen("temp.bin","wb"); 
    if (f) 
    { // not writing all the data, just a few examples 
    sprintf(buf,"%04d%s\00",12,"economic10"); fwrite(buf,sizeof(char),strlen(buf)+1,f); 
    sprintf(buf,"%04d%s\00",13,"science5"); fwrite(buf,sizeof(char),strlen(buf)+1,f); 
    sprintf(buf,"%04d%s\00",14,"music1"); fwrite(buf,sizeof(char),strlen(buf)+1,f); 
    sprintf(buf,"%04d%s\00",15,"physics9"); fwrite(buf,sizeof(char),strlen(buf)+1,f); 
    fclose(f); 
    } 
    // read dummy bin file 
    f = fopen("temp.bin","rb"); 
    if (f) 
    { 
    int classID; 
    char str[64]; 
    char *pData 
    long offset = 0; 
    do 
    { 
    fseek(f,offset,SEEK_SET); 
    pData = fgets(buf,BUFSIZE,f); 
    if (pData) 
    { sscanf(buf,"%04d%s",&classID,&str); 
     printf("%d\t%s\r\n",classID,str); 
     offset +=strlen(pData)+1; // record + 1 null character 
    } 
    } while(pData); 
    fclose(f); 
    } 
    getchar(); 
    return 0; 
} 
 
関連する問題