Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: Writing to file using fwrite?

  1. #1
    Join Date
    Mar 2008
    Location
    Ireland
    Beans
    767
    Distro
    Ubuntu 14.04 Trusty Tahr

    Writing to file using fwrite?

    Hey all,

    I can write simple variables out to a file but the problem is I have more complex things to write out. (such as structs and 2D arrays)

    For writing out a struct I tried this:


    Code:
    FILE * WRITE = fopen(fileName, "w+b");
    
    fwrite(&charData, sizeof(struct charData),1, WRITE);
     
    fclose(WRITE);
    However, I get a weird error about "missing lvalues". What does it mean?
    Projects: PhotoFiltre LX | Xwii | URT-2D | TTM

  2. #2
    Join Date
    May 2007
    Location
    Leeds, UK
    Beans
    1,664
    Distro
    Ubuntu 13.10 Saucy Salamander

    Re: Writing to file using fwrite?

    Is charData the name of a struct or the name of a variable?
    Please create new threads for new questions.
    Please wrap code in code tags using the '#' button or enter it in your post like this: [code]...[/code].

  3. #3
    Join Date
    Aug 2010
    Location
    Lancs, United Kingdom
    Beans
    1,093
    Distro
    Xubuntu 14.04 Trusty Tahr

    Re: Writing to file using fwrite?

    Quote Originally Posted by fallenshadow View Post
    Hey all,

    I can write simple variables out to a file but the problem is I have more complex things to write out. (such as structs and 2D arrays)

    For writing out a struct I tried this:


    Code:
    FILE * WRITE = fopen(fileName, "w+b");
    
    fwrite(&charData, sizeof(struct charData),1, WRITE);
     
    fclose(WRITE);
    However, I get a weird error about "missing lvalues". What does it mean?
    With a minimal wrapping to turn your code fragment into a complete program, your code compiles and executes correctly. e.g.
    Code:
    #include <stdio.h>
    
    struct charData { char buffer[8] ; } charData;
    
    int main()
    {
      const char * fileName = "fubar.dat";
      FILE * WRITE = fopen(fileName, "w+b");
    
      fwrite(&charData, sizeof(struct charData),1, WRITE);
     
      fclose(WRITE);
    
      return 0;
    }
    This suggests that your problem lies elsewhere. Your code fragment could be invalid if WRITE is a macro, or if charData isn't declared appropriately. Of course, in real code, you'd want to test the return values of fopen, fread, fwrite.

    In simple terms, an lvalue is an expression that can appear on the left-hand side of the assignment operator '=', but there are other contexts where an lvalue is required.

    There are arguments advising against writing a struct as a whole rather than its members. However, there are contexts where writing a whole struct can "work".

  4. #4
    Join Date
    Mar 2008
    Location
    Ireland
    Beans
    767
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Writing to file using fwrite?

    Is charData the name of a struct or the name of a variable?
    CharData is a struct. Here is my full code for this:

    Code:
    #include <stdio.h>
    
    int saves[3];
    int party[3];
    int equipment[27];
    
    struct charData {
        int class, attack, defense, crit, clan, level, xp, maxXp, hp, maxHp, aura, maxAura, mysticAtk,
        mysticDef, hpBonus, atkBonus, defBonus, vit, aur, range, str, luck, rangeBonus, mAtkBonus,
        mdefBonus, upgradePoints, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, s1, s2, s3, s4, s5, s6, s7,
        s8,s9,s10, weight, maxWeight;
    
        char*name;
        char*portrait;
        char*portraitLG;
        char*type;
        char*cond;
        char*loc;
    };
    
    struct charData CharDataArray[10];
    
    
    void setCharData()
    {
     CharDataArray[1].name="Jarrett";
     CharDataArray[1].class=1;
     CharDataArray[1].type="Knight";
     CharDataArray[1].portrait="jarrett";
     CharDataArray[1].portraitLG="jarrettLG";
     CharDataArray[1].level=1;
     CharDataArray[1].xp=0;
     CharDataArray[1].maxXp=60;
     CharDataArray[1].hp=30;
     CharDataArray[1].maxHp=30;
     CharDataArray[1].aura=10;
     CharDataArray[1].maxAura=10;
     CharDataArray[1].cond="Healthy";
     CharDataArray[1].attack=4;
     CharDataArray[1].defense=3;
     CharDataArray[1].crit=1;
     CharDataArray[1].mysticAtk=1;
     CharDataArray[1].mysticDef=1;
     CharDataArray[1].vit=1;
     CharDataArray[1].aur=1;
     CharDataArray[1].range=1;
     CharDataArray[1].str=1;
     CharDataArray[1].luck=1;
     CharDataArray[1].clan=0;
     CharDataArray[1].hpBonus=0;
     CharDataArray[1].atkBonus=0;
     CharDataArray[1].upgradePoints=8;
     CharDataArray[1].a1=1;
     CharDataArray[1].a2=2;
     CharDataArray[1].a3=3;
     CharDataArray[1].a4=4;
     CharDataArray[1].a5=5;
     CharDataArray[1].a6=6;
     CharDataArray[1].a7=7;
     CharDataArray[1].a8=8;
     CharDataArray[1].a9=9;
     CharDataArray[1].a10=10;
     CharDataArray[1].s1=1;
     CharDataArray[1].s2=4;
     //CharDataArray[1].s3=3;
     //CharDataArray[1].s4=4;
     //CharDataArray[1].s5=5;
     CharDataArray[1].weight=22;
     CharDataArray[1].maxWeight=100;
     CharDataArray[1].loc="Konia village";
    
     CharDataArray[2].name="Lorne";
     CharDataArray[2].class=2;
     CharDataArray[2].type="Rogue";
     CharDataArray[2].portrait="lorne";
     CharDataArray[2].portraitLG="lorneLG";
     CharDataArray[2].level=1;
     CharDataArray[2].xp=0;
     CharDataArray[2].maxXp=40;
     CharDataArray[2].hp=20;
     CharDataArray[2].maxHp=20;
     CharDataArray[2].aura=20;
     CharDataArray[2].maxAura=20;
     CharDataArray[2].cond="Healthy";
     CharDataArray[2].attack=2;
     CharDataArray[2].defense=1;
     CharDataArray[2].crit=2;
     CharDataArray[2].mysticAtk=3;
     CharDataArray[2].mysticDef=2;
     CharDataArray[2].vit=1;
     CharDataArray[2].aur=1;
     CharDataArray[2].range=1;
     CharDataArray[2].str=1;
     CharDataArray[2].luck=1;
     CharDataArray[2].clan=0;
     CharDataArray[2].hpBonus=0;
     CharDataArray[2].atkBonus=0;
     CharDataArray[2].upgradePoints=5;
     CharDataArray[2].a1=11;
     CharDataArray[2].a2=12;
     CharDataArray[2].a3=13;
     CharDataArray[2].a4=14;
     CharDataArray[2].a5=15;
     CharDataArray[2].a6=16;
     CharDataArray[2].a7=17;
     CharDataArray[2].a8=18;
     CharDataArray[2].a9=19;
     CharDataArray[2].a10=20;
     
     CharDataArray[3].name="Aissa";
     CharDataArray[3].class=3;
     CharDataArray[3].type="Mage";
     CharDataArray[3].portrait="aissa";
     CharDataArray[3].portraitLG="aissaLG";
     CharDataArray[3].level=1;
     CharDataArray[3].xp=0;
     CharDataArray[3].maxXp=80;
     CharDataArray[3].hp=40;
     CharDataArray[3].maxHp=40;
     CharDataArray[3].aura=30;
     CharDataArray[3].maxAura=30;
     CharDataArray[3].cond="Healthy";
     CharDataArray[3].attack=1;
     CharDataArray[3].defense=1;
     CharDataArray[3].crit=1;
     CharDataArray[3].mysticAtk=5;
     CharDataArray[3].mysticDef=2;
     CharDataArray[3].vit=1;
     CharDataArray[3].aur=1;
     CharDataArray[3].range=1;
     CharDataArray[3].str=1;
     CharDataArray[3].luck=1;
     CharDataArray[3].clan=0;
     CharDataArray[3].hpBonus=0;
     CharDataArray[3].atkBonus=0;
     CharDataArray[3].upgradePoints=3;
     CharDataArray[3].a1=21;
     CharDataArray[3].a2=22;
     CharDataArray[3].a3=23;
     CharDataArray[3].a4=24;
     CharDataArray[3].a5=25;
     CharDataArray[3].a6=26;
     CharDataArray[3].a7=27;
     CharDataArray[3].a8=28;
     CharDataArray[3].a9=29;
     CharDataArray[3].a10=30;
    }
    
    int main()
    {
      setCharData();
    	
      const char * fileName = "fubar.dat";
      FILE * WRITE = fopen(fileName, "w+b");
    
      fwrite(&charData, sizeof(struct charData),1, WRITE);
     
      fclose(WRITE);
    
      return 0;
    }
    @spjackson: You are right the code does compile for an empty struct so the problem must be my data setup.
    Projects: PhotoFiltre LX | Xwii | URT-2D | TTM

  5. #5
    Join Date
    Aug 2010
    Location
    Lancs, United Kingdom
    Beans
    1,093
    Distro
    Xubuntu 14.04 Trusty Tahr

    Re: Writing to file using fwrite?

    The difference between my code and yours is that I have a variable called charData but you don't. Here are a few things you might mean:
    Code:
      fwrite(&CharDataArray, sizeof(CharDataArray),1, WRITE); // write whole array
      fwrite(&CharDataArray, sizeof(struct charData),1, WRITE); //write just CharDataArray[0], which is all 0s
      fwrite(&CharDataArray, sizeof(struct charData),4, WRITE); //write array elements 0, 1, 2, 3
      fwrite(&CharDataArray, sizeof(struct charData),10, WRITE); // another way to write the whole array
    But your use case is an excellent example of why NOT to write a struct. For all those char pointers, you will write out the addresses they point to. What use will that be?

  6. #6
    Join Date
    Mar 2008
    Location
    Ireland
    Beans
    767
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Writing to file using fwrite?

    This one seems to work for the ints but the Char* items are all messed up. However, I am attempting to write out the full struct array, so im on the right track at least.

    Code:
    fwrite(&CharDataArray, sizeof(struct charData),10, WRITE); // another way to write the whole array
    For all those char pointers, you will write out the addresses they point to. What use will that be?
    Ah, so for the Char* to not be corrupted I have to do what? Im not sure I understand you.
    Projects: PhotoFiltre LX | Xwii | URT-2D | TTM

  7. #7
    Join Date
    May 2007
    Location
    Leeds, UK
    Beans
    1,664
    Distro
    Ubuntu 13.10 Saucy Salamander

    Re: Writing to file using fwrite?

    When you write out the struct, the char pointers become useless because they point to a memory location that has no meaning next time the program runs.

    Code:
    +----------+
    | char *s1 | --> "abc\0"
    +----------+
    | char *s2 | --> "def\0"
    +----------+
    | char *s3 | --> "ghi\0"
    +----------+
    You are only saving the memory inside the boxes, i.e. the pointers, not the memory pointed to by the pointers, i.e. the characters of the strings.
    Please create new threads for new questions.
    Please wrap code in code tags using the '#' button or enter it in your post like this: [code]...[/code].

  8. #8
    Join Date
    Mar 2008
    Location
    Ireland
    Beans
    767
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Writing to file using fwrite?

    Ahh, now I get it. So I have to record the addresses somewhere and then... ugh this is a mess. T_T
    Projects: PhotoFiltre LX | Xwii | URT-2D | TTM

  9. #9
    Join Date
    Aug 2011
    Location
    47°9′S 126°43W
    Beans
    1,876
    Distro
    Kubuntu 12.10 Quantal Quetzal

    Re: Writing to file using fwrite?

    Quote Originally Posted by fallenshadow View Post
    Ahh, now I get it. So I have to record the addresses somewhere and then... ugh this is a mess. T_T
    No, you have to write your strings in full... you can't really have you file mapping the structure directly. I would strongly recommend doing something more robust like writing each structure item as a formatted string on its own line (or even better saving the whole in some ini-like format). Yes, that means some function to write/read the struct, handle errors, etc... but in the long run it will make lots of thing easier.

  10. #10
    Join Date
    Mar 2008
    Location
    Ireland
    Beans
    767
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Writing to file using fwrite?

    I have a bit of a problem though, this code is used within GameEditor and it seems I can't use strings. :/

    This is why I am using Char*.
    Projects: PhotoFiltre LX | Xwii | URT-2D | TTM

Page 1 of 3 123 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •