Thread: Write and read struct to txt file

  1. #1
    Registered User
    Join Date
    Nov 2017
    Posts
    18

    Write and read struct to txt file

    Part of the program is in swedish. But i have translated the menu.
    My question is basically how to get fwrite and fread to work with my "structure"


    My program inputs data from user and saves that in struct of max 10 posts.
    Code:
    /* Data av typen fordon */
    typedef struct fordon { /* "vehicle*/ 
        char namn[15];    /* name of the owner */
        char marke[20];    /* car brand */
        char fordonstyp[15];
        char registeringsnummer[10];
    } fordon;
      fordon f[10];
    Menu option 5 writes out the vehicle directory.
    Write and read struct to txt file-2-png

    In the beginning of the "main function". I want the program to import posts to the vehicle directory from a .txt file. If it exists any file.

    Menu option 6 ends the program. At that point i want the vehicle directory to be written to a txt.file. I kinda got that code in place. At least it creates a file.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    /* Data av typen fordon */
    typedef struct fordon { /* "vehicle*/ 
        char namn[15];    /* name of the owner */
        char marke[20];    /* car brand */
        char fordonstyp[15];
        char registeringsnummer[10];
    } fordon;
      fordon f[10];
      
    
    /* Data av typen fordon */
    typedef struct person {
        char id[40];
        int alder;
    } person;
      person p;
    
    
    /* Funktion lägg till fordon */
    bool add(fordon* f) {
      fordon tmp;
      printf("Enter name of owner: ");
      scanf("%s", tmp.namn);                                  /* name of the owner */
      printf("Enter car brand: ");
      scanf("%s", tmp.marke);                               /* car brand */
      /*printf("fordonstyp: ");
      scanf("%s", tmp.fordonstyp);
      printf("registeringsnummer: ");
      scanf("%s", tmp.registeringsnummer);*/
      /* Läs in allt data och lägg i tmp */
    
    
    
      *f = tmp;
      return true; // Allt gick bra
    }
    /* Funktion ta bort fordon */
    bool delete(fordon* f){
    fordon tmp;
    int i = 0;
    
    memset(&tmp.namn[0], 0, sizeof(tmp.namn));
    memset(&tmp.marke[0], 0, sizeof(tmp.marke));
    memset(&tmp.fordonstyp[0], 0, sizeof(tmp.fordonstyp));
    memset(&tmp.registeringsnummer[0], 0, sizeof(tmp.registeringsnummer));
    
    *f = tmp;
    return true;
    }
    /* Sort after car brand*/
    void sortera(){
      int i,j;
    
      fordon temp;
    
    for (int i = 0; i < 10; i++) 
      {
          for (int j = i+1; j < 10; j++)
          {
                if (strcmp(f[i].marke, f[j].marke) > 0 && f[j].marke[0] != '\0')
                {
                    temp = f[i]; 
                    f[i] = f[j]; 
                    f[j] = temp; 
                }
            }
        }
    }
    
    int main() {
    int val = 0, i = 0;
    /*
    FILE *file = fopen("a.txt", "w");
    for (i = 0; i < 10; i++) {
        fordon *p = malloc(sizeof (fordon));
        fread(p, sizeof (fordon), 1, file);
        f[i] = p; 
    }
    fclose(file); */
    
    /* switch meny */
    
    while(val != 6){
    
      printf("\n1. Add a vehicle");
      printf("\n2. Remove a vehicle");
      printf("\n3. Sort by car brand");
      printf("\n4. Print out iinformation about a veichle");
      printf("\n5. Print out vehicle directory");
      printf("\n6. End\n");
      printf("Enter a choice (1-6) ");
    
    scanf("%d", &val);
    
    switch(val){
    case 1:
    i = 0;
    while(  f[i].namn[0] != '\0' && i < 10){
    i++;}
    printf("(%d)", i+1);
    if(f[9].namn[0] != '\0'){
    printf("\n Registret är fullt\n");
    break;
    
    
    }
    else{
     add(&f[i]);
    break;}
    break;
    
    case 2:
    i= 0;
    printf("\nSkriv in platsen(1-10) på det fordon du vill ta  bort: ");
    scanf("%d", &i);
    delete(&f[i-1]);
    break;
    
    case 3:
    sortera();
    break;
    
    case 4:
    i = 0;
    printf("\nSkriv in platsen(1-10) på det fordon du vill skriva ut information om: ");
    scanf("%d", &i);
    if(i < 1 || i >10){
    ("\nFel! Välj någon av platserna 1-10.\n");}
    
    else if (f[i-1].namn[0] == '\0'){
    printf("\nPlatsen är tom.\n");}
    else {
    printf("%d.%s    %s    %s    %s\n", i, f[i-1].namn, f[i-1].marke,  f[i-1].fordonstyp, f[i-1].registeringsnummer);}
    break;
    
    case 5:
    for(i=0; i<10; i++){
    printf("%d.%s    %s    %s    %s\n", i + 1, f[i].namn, f[i].marke,  f[i].fordonstyp, f[i].registeringsnummer)  ;}
    break;
    
    case 6:
    break;
    
    default:
    printf("\nFel! Välj något av alternativen 1-6.\n");
    }
    }
    /* Skriv ut till fil */
     FILE *file = fopen("a.txt", "w");
    
    
    for (i = 0; i < 10; i++) {
        fwrite(&f[i], sizeof (fordon), 1, file);
    }
    fclose(file);
    return 0;
    
    }
    Attached Images Attached Images Write and read struct to txt file-1-png 
    Last edited by Heisenberg800; 11-28-2017 at 12:01 PM.

  2. #2
    Banned
    Join Date
    Aug 2017
    Posts
    861
    OK I am going to give you some code I wrote it takes from a flat file. With the data in the proper format adds it to the struct then writes it to a bin file, then it reads from that bin file and it is able to have the user select the amount of files wanted and which ones.

    You can use it to implement what you seem to be wanting to do with yours. it is there. you just need to weed it out, examine it then use it to your liking it is open source so its yours to do with what you will.

    ( PS I used your code as a templet , so yeah )
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define BINFILE "black_ops.bin"
    
    typedef struct RECORDS_OF_INTREST
    {
        int id; 
        char name[200];
        char address [300];
        double acc_bal;    
    }rec_of_intrest;
    
    rec_of_intrest set_of_rec[400];
    
    int main(int argc, const char **argv)
    {
        // if use does not add anything other than program name.
        if ( argc < 2)
        {
            printf("Usage:\n"
                    "%s [data file]\n"
                    "your output file is \n"
                    "named %s\n", argv[0], BINFILE);
            return -1;
        }
        
        int cnt = 0 , amount=0;
        //int len = 0;
         // read flat file for data input
         FILE *fp;
         //for binary files
         FILE *bfp;
         
         if ( ( fp = fopen(argv[1], "r") ) == NULL )
         {
             printf("No File present\n"
                    "Contact head of state\n"
                    "to see what happened to it.\n"
                    "Phone Number should be in the\n"
                    "yellow pages\n");
            exit(1);
        }
        if (( bfp = fopen(BINFILE, "wb+") ) == NULL)
        {
             printf("No File present\n"
                    "Contact head of state\n"
                    "to see what happened to it.\n"
                    "Phone Number should be in the\n"
                    "yellow pages\n");
            exit(1);
        }  // string with spaces unknown amount %*s %[^\n] end line
        // adding that it no longer gets first line
        
        char buff[1024]; // 4 fgets to null of file
        while ( fscanf(fp, "%d%s%*s%299[^\n]%lf",&set_of_rec[cnt].id,set_of_rec[cnt].name,set_of_rec[cnt].address,&set_of_rec[cnt].acc_bal) 
        && fgets(buff, sizeof buff, fp) != NULL)
        {
         // to just shove all of the struct data into the bin file all at one time
            fwrite(&set_of_rec,sizeof(set_of_rec), 1, bfp);
        //    printf("cnt %d: %d %s %s %.2lf\n",cnt,set_of_rec[cnt].id,set_of_rec[cnt].name,set_of_rec[cnt].address,set_of_rec[cnt].acc_bal);
            cnt++;
        }
        fclose(fp);
        fclose(bfp);
        
        if ( (bfp = fopen(BINFILE, "rb+") ) == NULL)
        {
            printf("Someone took it, or I just cannot\n"
                    "access the file. Notify Head of State\n");
            exit(1);
        }
        
        /*
        printf("enter record number wanted to see\n"
                "record amount is %d\n", cnt);
        int rec;
        scanf("%d", &rec);
            
        if ( rec <= cnt)
        {
        cnt = 0;
        while (fread(&set_of_rec, sizeof(set_of_rec), 1, bfp) > 0) 
        {
            
            if (set_of_rec[cnt].id == rec)
            {
                len = ftell(bfp);
                printf("LEN1 = %d\n", len);
                printf("Id, Name, Address, amount in account\n");
                printf("\n%d %s %s %.2lf\n", set_of_rec[cnt].id,set_of_rec[cnt].name,set_of_rec[cnt].address,set_of_rec[cnt].acc_bal);
                len = ftell(bfp);
                printf("LEN2 = %d\n", len);
                break;
            }
            
            cnt++;
        }
     
        
        }
        * */
    //    size_t where_to_go; 
        int recs[5];
     // get multi "random user selected" records 
        //fseek(bfp,0,SEEK_SET);
        fseek(bfp,(1*sizeof(set_of_rec[0])),SEEK_SET);
        printf("Enter amount of records wanted, and which ones\n"
                "enter up to 5 records\n");
                scanf("%d", &amount);
                
        switch (amount)
        {
            case 1:
                scanf("%d", &recs[0]);
                break;
            case 2:
                scanf("%d%d",&recs[0],&recs[1]);
                break;
            case 3:
                scanf("%d%d%d", &recs[0],&recs[1],&recs[2]);
                break;
            case 4:
                scanf("%d%d%d%d", &recs[0],&recs[1],&recs[2],&recs[3]);
                break;
            case 5:
                scanf("%d%d%d%d%d", &recs[0],&recs[1],&recs[2],&recs[3],&recs[4]);
                break;
            default:
                break;
        }
        printf("  Id, Name, Address, amount in account\n");
        for(int i = 0; i < amount; i++)
        {
        //    printf("pos1 %ld\n",ftell(bfp) );
        //    size_t size = (1*sizeof(set_of_rec));
        //    printf("size: %zu\n", size);
        //    where_to_go =  (recs[i] * (1*sizeof(set_of_rec)));
             
        //    printf("where_to_go %zu\n", where_to_go);
        //    fseek(bfp, where_to_go, SEEK_SET);         
            fseek(bfp, (recs[i] * sizeof(set_of_rec)), SEEK_SET);         
    //        fseek(bfp, where_to_go, SEEK_SET);         
        //    printf("pos2 %ld\n",ftell(bfp));
        //    printf("rec #%d\n",recs[i]);
        //    printf("i = %d\n",i);
            fread(&set_of_rec, sizeof(set_of_rec),4, bfp);
            
            printf("\n%d %s %s %.2lf\n", set_of_rec[recs[i]-1].id,set_of_rec[recs[i]-1].name,set_of_rec[recs[i]-1].address,set_of_rec[recs[i]-1].acc_bal);
            //fseek(bfp,(1*sizeof(set_of_rec[0])),SEEK_SET); //reset it back to start
        }
        
        fclose(bfp);
        
    return 0;    
    }
    Code:
    $ ./Binary_read_write input_data
    Enter amount of records wanted, and which ones
    enter up to 5 records
    3 5 3 2
      Id, Name, Address, amount in account
    
    5 sally  sally street 34.43
    
    3 jill  jill street 45.33
    
    2 sally  sally street 30.44
    data file
    Code:
    1
    bob
    1234 bobs street
    23.44
    2
    sally
    3456 sally street
    30.44
    3
    jill
    3243 jill street
    45.33
    4
    bob
    1234 bobs street
    23.44
    5
    sally
    3456 sally street
    34.43
    6
    jill
    3243 jill street
    340.33
    7
    bob
    1234 bobs street
    23.44
    8
    sally
    3456 sally street
    30.44
    9
    jill
    3243 jill street
    40.33
    10
    bob
    1234 bobs street
    23.44
    11
    sally
    3456 sally street
    30.44
    12
    jill
    3243 jill street
    4370.33
    hopefully it will help you to get a better perspective on how to do what you're wanting to do.

    even that code has room for improvement or a different method for printing out the files, I'm thinking using a loop, so the switch will not be there , as it could get really long for more then 5 files, but have not bothered to figure it out.
    Last edited by userxbw; 11-28-2017 at 01:09 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 19
    Last Post: 01-04-2013, 11:20 PM
  2. Replies: 2
    Last Post: 01-02-2013, 11:03 PM
  3. Replies: 12
    Last Post: 06-18-2012, 08:23 AM
  4. multiway read\write struct
    By quantt in forum C Programming
    Replies: 2
    Last Post: 02-02-2009, 10:13 AM
  5. Read/write file help
    By erictran in forum C Programming
    Replies: 4
    Last Post: 09-20-2006, 10:17 AM

Tags for this Thread