writing into file using structures

Discussion in 'C Programming' started by sweeet_addiction16@yahoo.com, Sep 1, 2007.

  1. Guest

    hello experts...pls help me debug this code........im not able to
    write in the data bytes ..only the few header bytes are written...

    #include<stdio.h>

    struct mthd_chunk
    {

    char id[4];
    unsigned long Length; /* This will be 6 */

    /* Here are the 6 bytes */
    unsigned short Format;
    unsigned short NumTrack;
    unsigned short Division;
    };

    struct MTRK_CHUNK
    {
    /* Here's the 8 byte header that all chunks must have */
    char ID[4]; /* This will be 'M','T','r','k' */
    unsigned long Length; /* This will be the actual size of
    Data[] */

    /* Here are the data bytes */
    unsigned char Data[20]; /* Its actual size is Data[Length]
    */
    };

    int main()
    {
    FILE *fp;
    struct mthd_chunk mthd;
    struct MTRK_CHUNK mtrk;
    mthd.id[0]=0x4d;
    mthd.id[1]=0x54;
    mthd.id[2]=0x68;
    mthd.id[3]=0x64;
    mthd.Length=0x00000006;
    mthd.Format=0x0000;
    mthd.NumTrack=0x0001;
    mthd.Division=0x0080;

    mtrk.ID[0]=0x4d;
    mtrk.ID[1]=0x54;
    mtrk.ID[2]=0x72;
    mtrk.ID[3]=0x6b;
    mtrk.Length=0x0000000d;

    mtrk.Data[0]=0x40;
    mtrk.Data[1]=0x90;
    mtrk.Data[2]=0x3c;
    mtrk.Data[3]=0x1e;
    mtrk.Data[4]=0x82;
    mtrk.Data[5]=0x00;
    mtrk.Data[6]=0x90;structures in c
    mtrk.Data[7]=0x3c;
    mtrk.Data[8]=0x00;

    mtrk.Data[9]=0x00;
    mtrk.Data[10]=0xff;
    mtrk.Data[11]=0x2f;
    mtrk.Data[12]=0x00;


    fp=fopen("star.mid","w");
    fwrite(&mthd,sizeof mthd,1,fp);
    fwrite(&mtrk,sizeof mtrk,1,fp);

    }
     
    , Sep 1, 2007
    #1
    1. Advertising

  2. <> wrote in message
    news:...
    > hello experts...pls help me debug this code........im not able to
    > write in the data bytes ..only the few header bytes are written...
    >
    > #include<stdio.h>
    >
    > struct mthd_chunk
    > {
    >
    > char id[4];
    > unsigned long Length; /* This will be 6 */
    >
    > /* Here are the 6 bytes */
    > unsigned short Format;
    > unsigned short NumTrack;
    > unsigned short Division;
    > };
    >
    > struct MTRK_CHUNK
    > {
    > /* Here's the 8 byte header that all chunks must have */
    > char ID[4]; /* This will be 'M','T','r','k' */
    > unsigned long Length; /* This will be the actual size of
    > Data[] */
    >
    > /* Here are the data bytes */
    > unsigned char Data[20]; /* Its actual size is Data[Length]
    > */
    > };
    >
    > int main()
    > {
    > FILE *fp;
    > struct mthd_chunk mthd;
    > struct MTRK_CHUNK mtrk;
    > mthd.id[0]=0x4d;
    > mthd.id[1]=0x54;
    > mthd.id[2]=0x68;
    > mthd.id[3]=0x64;
    > mthd.Length=0x00000006;
    > mthd.Format=0x0000;
    > mthd.NumTrack=0x0001;
    > mthd.Division=0x0080;
    >
    > mtrk.ID[0]=0x4d;
    > mtrk.ID[1]=0x54;
    > mtrk.ID[2]=0x72;
    > mtrk.ID[3]=0x6b;
    > mtrk.Length=0x0000000d;
    >
    > mtrk.Data[0]=0x40;
    > mtrk.Data[1]=0x90;
    > mtrk.Data[2]=0x3c;
    > mtrk.Data[3]=0x1e;
    > mtrk.Data[4]=0x82;
    > mtrk.Data[5]=0x00;
    > mtrk.Data[6]=0x90;structures in c
    > mtrk.Data[7]=0x3c;
    > mtrk.Data[8]=0x00;
    >
    > mtrk.Data[9]=0x00;
    > mtrk.Data[10]=0xff;
    > mtrk.Data[11]=0x2f;
    > mtrk.Data[12]=0x00;
    >
    >
    > fp=fopen("star.mid","w");
    > fwrite(&mthd,sizeof mthd,1,fp);
    > fwrite(&mtrk,sizeof mtrk,1,fp);
    >
    > }
    >

    This is where the struct hack comes unstuck.
    sizeof mtrk will be only 20 + 4 + a few for the long.

    To write it do so member by member

    fwrite(mtrk.ID, 1, 4, fp):
    fwrite(&mtrk.Length, sizeof(unsigned long), 1, fp):
    fwrite(mtrk.data, mtrk.Length, 1, fp);

    Note that if you want the code to be portable you cannot write a raw
    unsigned long, as it may be 32 or 64 bits on common systems, and even a
    different number on some oddballs.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
     
    Malcolm McLean, Sep 1, 2007
    #2
    1. Advertising

  3. On Sep 1, 9:27 am, wrote:
    > hello experts...pls help me debug this code........im not able to
    > write in the data bytes ..only the few header bytes are written...


    [code snipped]
    Have you actually tried this code? Apart from the missing fclose()
    call at the end of main() everything works perfectly.
    Is MTRK_CHUNK really defined like you metioned? Or is it define like
    this?

    struct MTRK_CHUNK
    {
    char ID[4];
    unsigned long Length;
    unsigned char *Data; /* Data is not an array but a pointer */
    };

    If that's the case then you can use Macolm's suggestion or create a
    "variable-size structure".
    http://www.ddj.com/cpp/184403480

    Abdo Haji-Ali
    Programmer
    In|Framez
     
    Abdo Haji-Ali, Sep 1, 2007
    #3
  4. On Sat, 01 Sep 2007 00:27:31 -0700,
    wrote:

    >hello experts...pls help me debug this code........im not able to
    >write in the data bytes ..only the few header bytes are written...


    How do you know this? What technique are you using to examine the
    output?

    >
    >#include<stdio.h>
    >
    >struct mthd_chunk
    > {
    >
    > char id[4];
    > unsigned long Length; /* This will be 6 */
    >
    > /* Here are the 6 bytes */
    > unsigned short Format;
    > unsigned short NumTrack;
    > unsigned short Division;
    > };
    >
    > struct MTRK_CHUNK
    > {
    > /* Here's the 8 byte header that all chunks must have */
    > char ID[4]; /* This will be 'M','T','r','k' */
    > unsigned long Length; /* This will be the actual size of
    >Data[] */
    >
    > /* Here are the data bytes */
    > unsigned char Data[20]; /* Its actual size is Data[Length]
    >*/
    > };
    >
    >int main()


    int main(void) to be portable.

    >{
    > FILE *fp;
    > struct mthd_chunk mthd;
    > struct MTRK_CHUNK mtrk;
    > mthd.id[0]=0x4d;


    These values are ASCII specific and don't work on my system. Is there
    some reason you could not use 'M', 'T', 'r', etc.

    > mthd.id[1]=0x54;
    > mthd.id[2]=0x68;
    > mthd.id[3]=0x64;
    > mthd.Length=0x00000006;
    > mthd.Format=0x0000;
    > mthd.NumTrack=0x0001;
    > mthd.Division=0x0080;
    >
    > mtrk.ID[0]=0x4d;
    > mtrk.ID[1]=0x54;
    > mtrk.ID[2]=0x72;
    > mtrk.ID[3]=0x6b;
    > mtrk.Length=0x0000000d;
    >
    > mtrk.Data[0]=0x40;
    > mtrk.Data[1]=0x90;
    > mtrk.Data[2]=0x3c;
    > mtrk.Data[3]=0x1e;
    > mtrk.Data[4]=0x82;
    > mtrk.Data[5]=0x00;
    > mtrk.Data[6]=0x90;structures in c
    > mtrk.Data[7]=0x3c;
    > mtrk.Data[8]=0x00;
    >
    > mtrk.Data[9]=0x00;
    > mtrk.Data[10]=0xff;
    > mtrk.Data[11]=0x2f;
    > mtrk.Data[12]=0x00;
    >
    >
    > fp=fopen("star.mid","w");


    You should check to insure the file opened properly.

    > fwrite(&mthd,sizeof mthd,1,fp);


    You should check to insure the write succeeded.

    > fwrite(&mtrk,sizeof mtrk,1,fp);


    You never close the file. Data may be left in the buffer.

    >
    >}



    Remove del for email
     
    Barry Schwarz, Sep 2, 2007
    #4
  5. On Sat, 1 Sep 2007 08:36:32 +0100, "Malcolm McLean"
    <> wrote:

    >
    ><> wrote in message
    >news:...
    >> hello experts...pls help me debug this code........im not able to
    >> write in the data bytes ..only the few header bytes are written...
    >>
    >> #include<stdio.h>
    >>
    >> struct mthd_chunk
    >> {
    >>
    >> char id[4];
    >> unsigned long Length; /* This will be 6 */
    >>
    >> /* Here are the 6 bytes */
    >> unsigned short Format;
    >> unsigned short NumTrack;
    >> unsigned short Division;
    >> };
    >>
    >> struct MTRK_CHUNK
    >> {
    >> /* Here's the 8 byte header that all chunks must have */
    >> char ID[4]; /* This will be 'M','T','r','k' */
    >> unsigned long Length; /* This will be the actual size of
    >> Data[] */
    >>
    >> /* Here are the data bytes */
    >> unsigned char Data[20]; /* Its actual size is Data[Length]
    >> */
    >> };
    >>
    >> int main()
    >> {
    >> FILE *fp;
    >> struct mthd_chunk mthd;
    >> struct MTRK_CHUNK mtrk;
    >> mthd.id[0]=0x4d;
    >> mthd.id[1]=0x54;
    >> mthd.id[2]=0x68;
    >> mthd.id[3]=0x64;
    >> mthd.Length=0x00000006;
    >> mthd.Format=0x0000;
    >> mthd.NumTrack=0x0001;
    >> mthd.Division=0x0080;
    >>
    >> mtrk.ID[0]=0x4d;
    >> mtrk.ID[1]=0x54;
    >> mtrk.ID[2]=0x72;
    >> mtrk.ID[3]=0x6b;
    >> mtrk.Length=0x0000000d;
    >>
    >> mtrk.Data[0]=0x40;
    >> mtrk.Data[1]=0x90;
    >> mtrk.Data[2]=0x3c;
    >> mtrk.Data[3]=0x1e;
    >> mtrk.Data[4]=0x82;
    >> mtrk.Data[5]=0x00;
    >> mtrk.Data[6]=0x90;structures in c
    >> mtrk.Data[7]=0x3c;
    >> mtrk.Data[8]=0x00;
    >>
    >> mtrk.Data[9]=0x00;
    >> mtrk.Data[10]=0xff;
    >> mtrk.Data[11]=0x2f;
    >> mtrk.Data[12]=0x00;
    >>
    >>
    >> fp=fopen("star.mid","w");
    >> fwrite(&mthd,sizeof mthd,1,fp);
    >> fwrite(&mtrk,sizeof mtrk,1,fp);
    >>
    >> }
    >>

    >This is where the struct hack comes unstuck.


    What struct hack? He has not placed a short array at the end of a
    structure and over-allocated space for it.

    >sizeof mtrk will be only 20 + 4 + a few for the long.


    Plus whatever is needed for alignment and arbitrary padding. Does he
    want to write any more?

    >
    >To write it do so member by member
    >
    >fwrite(mtrk.ID, 1, 4, fp):
    >fwrite(&mtrk.Length, sizeof(unsigned long), 1, fp):
    >fwrite(mtrk.data, mtrk.Length, 1, fp);
    >
    >Note that if you want the code to be portable you cannot write a raw
    >unsigned long, as it may be 32 or 64 bits on common systems, and even a
    >different number on some oddballs.



    Remove del for email
     
    Barry Schwarz, Sep 2, 2007
    #5
  6. On Sat, 01 Sep 2007 00:27:31 -0700,
    wrote:

    > struct mthd_chunk
    > {
    > char id[4];
    > unsigned long Length; /* This will be 6 */
    >
    > /* Here are the 6 bytes */
    > unsigned short Format;
    > unsigned short NumTrack;
    > unsigned short Division;
    > };
    >
    > struct MTRK_CHUNK
    > {
    > /* Here's the 8 byte header that all chunks must have */
    > char ID[4]; /* This will be 'M','T','r','k' */
    > unsigned long Length; /* This will be the actual size of
    > Data[] */
    >
    > /* Here are the data bytes */
    > unsigned char Data[20]; /* Its actual size is Data[Length]
    > */
    > };
    >
    > int main()
    > {
    > FILE *fp;
    > struct mthd_chunk mthd;
    > struct MTRK_CHUNK mtrk;

    <snip: fill in mthd.* and mtrk.ID>
    > mtrk.Length=0x0000000d;

    <snip: fill in mtrk.Data[0..0xC]>
    > fp=fopen("star.mid","w");


    Should check for failure. But that isn't your problem this time, since
    you say you did get partially correct output.

    > fwrite(&mthd,sizeof mthd,1,fp);


    This should work. But you should check the return value just in case.

    > fwrite(&mtrk,sizeof mtrk,1,fp);


    First, this will write the entire struct, including all 20 bytes of
    Data. If you want only the amount defined by the Length field, use
    fwrite (&mtrk, 1, offsetof(struct MTRK_CHUNK, Data) + mtrk.Length, fp)
    (or swap the two middle arguments if you like). If you do want all of
    it, and just use Length to identify the valid part, you might want to
    pad out the remaining bytes, to make it easier to look at, especially
    for debugging.

    Second, one of the bytes in .Length is 0x0D. This character has been
    used on some systems, although not many, as the C newline character
    \n; if your system is such, this byte may get translated into
    something different on text output, and back on input. On systems
    where it is not used so, it is not among the characters that the
    standard guarantees can be written to and read back from a text file.
    To deal with either of these, open the file in binary mode "wb".
    (Although on some systems, notably POSIX/Unix, this won't matter.)

    >
    > }

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Sep 16, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. HNguyen
    Replies:
    4
    Views:
    2,454
    HNguyen
    Dec 21, 2004
  2. tweak
    Replies:
    14
    Views:
    2,820
    Eric Sosman
    Jun 11, 2004
  3. Chance Ginger
    Replies:
    1
    Views:
    511
    Diez B. Roggisch
    Mar 14, 2006
  4. Alfonso Morra
    Replies:
    11
    Views:
    754
    Emmanuel Delahaye
    Sep 24, 2005
  5. uche
    Replies:
    6
    Views:
    414
    bnonaj
    Apr 4, 2007
Loading...

Share This Page