How to save/access information from a struct variable into/from a file?

This is a discussion on How to save/access information from a struct variable into/from a file? within the C Programming forums, part of the General Programming Boards category; I'm trying to do this program for school but I'm not very good at C and I'm not sure on ...

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    9

    How to save/access information from a struct variable into/from a file?

    I'm trying to do this program for school but I'm not very good at C and I'm not sure on how to do this. This program needs to read a vehicle registry with the owners name, the license plate and an additional variable to see if the registry was deleted or not. All the registries made need to be saved in a file and the user can choose to make a new registry or view them all (reading from the file I suppose) without showing the deleted ones. So I already made the base of the program, all that's left now is saving all in the file. I never worked with binary files so I have no idea how I should do this.

    Any help would be greatly appreciated. Thanks.

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define NAME_BUFFER_SIZE 80
    
    typedef struct {
    	char matricula[6];
    	char proprietario[NAME_BUFFER_SIZE];
    	char apagado; //iniciar a 0, != 0 = apagado
    } veiculo_t;
    
    //void inserir_registo();
    //{
    //}
    
    int main()
    {
    
    int opcao = 0;
    FILE *fp;
    veiculo_t registo;
    
    fp=fopen("registo.txt","ab+");
    
    do
    {
    printf("Escolha uma opção:\n1- Inserir Registo\n2- Imprimir todos os registos.\n3- Apagar registo\n4- Sair\n\n");
    scanf("%d", &opcao);
    
    switch( opcao )
    {
    case 1: 	printf("\nIntroduza a matricula do bino1\n\n");
    		scanf("%s",registo.matricula);
    		printf("%s\n",registo.matricula);
    		scanf("%s",registo.matricula);
    		printf("%s\n",registo.matricula);
    		break;
    case 2: 
    		printf("\nOption 2\n\n");
    		break;
    case 3: 
    		printf("\nOption 3\n\n");
    		break;
    default : 	
    		printf("\nBYE BYE!\n\n");
    		break;
    }
    }while (opcao != 4);
    
    
    
    return(0);
    }

  2. #2
    Nub SWE
    Join Date
    Mar 2008
    Location
    Dallas, TX
    Posts
    133
    All you need is to write something to a file?

    Code:
    FILE *fp_output;
    
    fp_output = fopen("registo.txt", "w");
    
    fprintf(fp_output, "Output this to the file.\n");

  3. #3
    Registered User
    Join Date
    Mar 2008
    Posts
    9
    Won't that be just text based? As in, if I open the file in notepad there will be that text there. So if I open it up it won't actually be opened as a variable.

    I need to save the entire struct variables ( veiculo_t registo; ) and its contents so they can be used again as a variable when I read the binary file.
    Last edited by Metalmurphy; 03-31-2008 at 03:23 PM.

  4. #4
    Nub SWE
    Join Date
    Mar 2008
    Location
    Dallas, TX
    Posts
    133
    Quote Originally Posted by Metalmurphy View Post
    Won't that be just text based? As in, if I open the file in notepad there will be that text there. So if I open it up it won't actually be opened as a variable.

    I need to save the entire struct variables (veiculo_t registo and its contents so they can be used again as a variable when I read the binary file.
    Yeah, I just didn't really understand your question. Thanks for clarification.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    So to write something to a file "as the computer sees it", you should use fwrite (and then read it in with fread).

  6. #6
    Registered User
    Join Date
    Mar 2008
    Posts
    9
    So i'll do fwrite(&registo,sizeof(veiculo_t),1,fp); ?

    What happens when I need to add the next car to the registry? Do I close and re-open the file with the append parameter?

    And one more question, when I'm reading the entire file again to display all the registries in the file how do I know when to stop reading? I'm guessing I'll do a for cycle with sizeof(veiculo_t)*i or something, but how do I know where the file finishes?

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Here is some old example code that is somewhat related.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Katy, Texas
    Posts
    2,309
    Try this on for learning. I just whooped it up as an exercise in fun.
    Code:
    #include <stdio.h>
    #include <string.h> 
    
    #define FILENAME "/Users/toddburch/struct.dat" 
    
    struct mystruct { 
    	char lname[31] ; 
    	char fname[21] ; 
    	int  address ; 
    	char street[31] ; 
    	char city[21] ; 
    	char state[3] ; 
    	int zip ; 
    } ; 
    
    
    int main (int argc, const char * argv[]) {
    
    	FILE * fp ; 
    	struct mystruct record, record2 ;  
    	char name[51] ; 
    	char address[51] ; 
    	char city_state_zip[51] ; 
    	char * blank, * blank2 ; 
    
    	printf("Enter First and Last Name...\n") ; 
    	fgets( name, sizeof(name), stdin) ;  
    	if (name[strlen(name)-1] == '\n') name[strlen(name)-1] = 0 ; 
    	blank = strchr(name, ' ') ; 
    	*blank = 0 ; 
    	strcpy(record.lname, name) ; 
    	strcpy(record.fname, blank+1) ; 
    
    	printf("Enter Street Address (# and street name)...\n") ; 
    	fgets( address, sizeof(address), stdin) ;  
    	if (address[strlen(address)-1] == '\n') address[strlen(address)-1] = 0 ; 
    	blank = strchr(address, ' ') ; 
    	*blank = 0 ; 
    	record.address = atoi(address) ; 
    	blank++ ;  
    	if (strlen(blank) > sizeof(record.street))  blank[sizeof(record.street)-1] = 0 ; // truncate it 
    	strcpy(record.street, blank) ; 
    
    	printf("Enter City, State (2 char abbreviation) and zip code...\n") ; 
    	fgets( city_state_zip, sizeof(city_state_zip), stdin) ;  
    	if (city_state_zip[strlen(city_state_zip)-1] == '\n') city_state_zip[strlen(city_state_zip)-1] = 0 ; 
    	blank = strchr(city_state_zip, ' ') ; 
    	*blank = 0 ; 
    	strcpy(record.city, city_state_zip) ; 
    	blank2 = ++blank ;  
    	blank = strchr(blank, ' ') ; 
    	*blank = 0 ; 
    	strcpy(record.state, blank2) ; 
    	record.zip = atoi(blank+1) ; 
    
    	fp = fopen( FILENAME, "wb") ; 
    	if (!fp) { 
    		printf("Cannot open output file.\n") ; 
    		return (-1) ; 
    	} 
    	
    	fwrite( &record, sizeof(record), 1, fp) ; 
    	fclose(fp) ;  
    
    	fp = fopen( FILENAME, "rb") ; 
    	if (!fp) { 
    		printf("Cannot open input file.\n") ; 
    		return (-1) ; 
    	} 
    	
    	fread( &record2, sizeof(record2), 1, fp) ; 
    	fclose(fp) ;  
    
    	printf("First/Last Name : &#37;s %s\n", record2.fname, record2.lname) ; 
    	printf("Address         : %d %s\n", record2.address, record2.street) ; 
    	printf("City, State, ZIP: %s %s %d\n", record2.city, record2.state, record2.zip) ; 
    
        return 0;
    }
    Last edited by Dino; 03-31-2008 at 10:52 PM. Reason: fname & lname were reversed.
    Mac and Windows cross platform programmer. Ruby lover.

    Quote of the Day
    12/20: Mario F.:I never was, am not, and never will be, one to shut up in the face of something I think is fundamentally wrong.

    Amen brother!

  9. #9
    Registered User
    Join Date
    Mar 2008
    Posts
    9
    Thanks alot Todd and Dave, those are indeed quite helpful. Hopefully I can finish my work in time (as in, in 3 hours ).


    Btw, why did you replace /n with a zero?
    Code:
    	if (name[strlen(name)-1] == '\n') name[strlen(name)-1] = 0 ;

  10. #10
    Registered User
    Join Date
    Mar 2008
    Posts
    9
    Hey guys, i'm having some problems with this:
    Code:
    case 1: 	printf("\nIntroduza a matricula do bino1\n\n");
    		fflush(stdin);
    		fgets(matricula,sizeof(matricula),stdin);
    		memcpy(&registo.matricula, &matricula, 6);
    The user is supposed to type a license plate and I need to make sure it only copies 6 characters from what he types. (It is requested in the paper that i need to use memcpy). But for some reason it's not allowing me to type anything, it just goes pass all that to the next line.

    Any idea what's wrong?

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,012
    Quote Originally Posted by Metalmurphy View Post
    Btw, why did you replace /n with a zero?
    Code:
    	if (name[strlen(name)-1] == '\n') name[strlen(name)-1] = 0 ;
    First, it's '\n', not '/n'. And it's because fgets leaves the newline character in the buffer and 99% of the times, you don't want it. So it checks if it's there and deletes it (truncates the string) if it's there.

    Quote Originally Posted by Metalmurphy View Post
    Hey guys, i'm having some problems with this:
    Code:
    case 1: 	printf("\nIntroduza a matricula do bino1\n\n");
    		fflush(stdin);
    		fgets(matricula,sizeof(matricula),stdin);
    		memcpy(&registo.matricula, &matricula, 6);
    The user is supposed to type a license plate and I need to make sure it only copies 6 characters from what he types. (It is requested in the paper that i need to use memcpy). But for some reason it's not allowing me to type anything, it just goes pass all that to the next line.

    Any idea what's wrong?
    Do not flush stdin. It's undefined behavior. Search the faq for a proper way to clear the input buffer instead.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Code:
    	if (name[strlen(name)-1] == '\n') name[strlen(name)-1] = 0 ;
    I'm not terribly fond of finding the end of the same string twice. A while back we tried different ways; these days I pretty much go with the strchr version shown in the FAQ.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Katy, Texas
    Posts
    2,309
    Yes, I like both the strchr and "foo" better, but strchr the best - less code for me to write. Thanks!

    Code:
    void foo(char *s, int c)
     {
       while (*s && *s != c)
       {
         s++;
       }
     
       *s = '\0';
     }
    Mac and Windows cross platform programmer. Ruby lover.

    Quote of the Day
    12/20: Mario F.:I never was, am not, and never will be, one to shut up in the face of something I think is fundamentally wrong.

    Amen brother!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 08:54 AM
  2. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 01:13 AM
  3. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 09:39 AM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 04:00 PM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 10:54 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21