Post your latest then
Post your latest then
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Okay
Savetofile();
And this is my readfromfile();Code:void savetofile() { FILE *fp; struct prs *this; struct prs *ptrthis; if(ptrfirst == NULL) { printf("Empty.\n"); return; } ptrthis = ptrfirst; if((fp=fopen("c:\\database.txt", "ab")) == NULL) { printf("No such file.\n"); return; } else { for ( this = ptrfirst ; this != NULL ; this = this->ptrnext ) { fwrite(this, sizeof(*this), 1, fp); fclose(fp); } printf("Saved.\n"); } }
Code:void readfromfile() { FILE *fp; struct prs temp; struct prs *next = NULL; fp=fopen("c:\\database.txt", "ab"); while(fread(&temp, sizeof(temp), 1, fp) > 0) { struct prs *new = malloc( sizeof *new ); // link new node into the list if ( ptrfirst == NULL ) { ptrfirst = new; } else { next->ptrnext = new; } // copy data new->number = temp.number; new->ptrnext = NULL; // this is now the tail of the list next = new; } fclose( fp ); }
Try not closing the file AFTER writing the first record, but AFTER writing all the records.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Ahh yes. Hmm, didn't help though :/
fread still returns 0.. I'm not sure where the error is.
Any other suggestions? This program have annoyed me for the past week
No one? :|
1) Write a program that will write the data in the form of text to your file. (Just fprintf each section.
2) Make sure there's actually data in the file.
3) Convert that into a program that just uses fwrite to write the structure.
4) Make sure there's data in the file.
5) Try using fread to read just one structure.
Quzah.
Hope is the first step on the road to disappointment.
Try this!
This is what the binary file looks likeCode:#include <stdio.h> #include <stdlib.h> typedef struct { char name[10]; int age; } data_st; typedef struct node_tag { data_st data; struct node_tag *next; } node_st; node_st *ListAlloc ( void ) { node_st *new = malloc( sizeof *new ); if ( new ) { new->next = NULL; } return new; } node_st *ListFill ( data_st *data ) { node_st *new = ListAlloc( ); if ( new ) { new->data = *data; } return new; } node_st *ListAppend ( node_st *head, data_st *data ) { node_st *new = ListFill( data ); if ( new ) { if ( !head ) { head = new; } else { node_st *tail = head; while ( tail->next ) tail = tail->next; tail->next = new; } } return head; } void ListSave ( node_st *list, char *filename ) { FILE *fp = fopen( filename, "wb" ); while ( list ) { fwrite( &list->data, sizeof list->data, 1, fp ); list = list->next; } fclose(fp); } node_st *ListLoad ( char *filename ) { FILE *fp = fopen( filename, "rb" ); node_st *list = NULL; data_st data; while ( fread( &data, sizeof data, 1, fp ) ) { list = ListAppend( list, &data ); } fclose(fp); return list; } void ListPrint ( node_st *list ) { while ( list ) { printf( "%s %d\n", list->data.name, list->data.age ); list = list->next; } } int main ( ) { data_st test[] = { { "fred", 22 }, { "barney", 23 }, { "wilma", 24 }, { "betty", 25 }, }; node_st *list = NULL, *loaded = NULL; int i; /* create a list */ for ( i = 0 ; i < 4 ; i++ ) { list = ListAppend( list, &test[i] ); } ListPrint( list ); /* save and load it */ ListSave( list, "wibble.bin" ); loaded = ListLoad( "wibble.bin" ); ListPrint( loaded ); return 0; }
Code:> od -t x1z wibble.bin 0000000 66 72 65 64 00 00 00 00 00 00 cc cc 16 00 00 00 >fred............< 0000020 62 61 72 6e 65 79 00 00 00 00 cc cc 17 00 00 00 >barney..........< 0000040 77 69 6c 6d 61 00 00 00 00 00 cc cc 18 00 00 00 >wilma...........< 0000060 62 65 74 74 79 00 00 00 00 00 cc cc 19 00 00 00 >betty...........< 0000100
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Salem why do you use pointers to functions? I mean I saw many implementations of Linked Lists and people usually don't use it. I've read your code its damm clear so I liked a lot your implementation. I just can't figure out why using it K&R gave me nothing great as feed back, any suggestions? I will google a while but if you could give me some tips I would be very gratefull thanks.
What? There's no function pointers there. There are functions that return pointers. But there are no function pointers.
Quzah.
Hope is the first step on the road to disappointment.
Oh I got it thanks a lot!Originally Posted by quzah
And to top this thread off with a cherry on top:
Code:#include <stdio.h> #include <stdlib.h> // A very strange linked list struct mendel { char name[255]; char SS[255]; struct mendel *next; }; // Mendel linked list data holder struct { struct mendel *first; struct mendel *curr; struct mendel *decoy; // Used just in case malloc fails } ListStatus; // Add to the linked list void add( void ); // List all of the information from the linked list void listAll( void ); int main( void ) { // c = temperary character for input // n = temperary character extracts bad \n char c; int n; // Make sure the linked list is NULL for now ListStatus.first = NULL; ListStatus.curr = NULL; // Ask the user for his/her next action puts( "'a' add data\n" "'l' list all\n" "'q' quit" ); printf( "~> " ); // Input from the user their linked list request while( c = getchar( ) ) { while( ( n=getchar( ) ) != EOF && n != '\n' ); switch( c ) { case 'a': add( ); break; case 'l': listAll( ); break; case 'q': puts( "Good bye." ); return 0; default: puts( "Bad input :( " ); } printf( "~> " ); } // Return success return 0; } // Add to the linked list void add( void ) { // fdb = File database for the linked list // ptr = Helps remove '\n' from fgets() FILE *fdb; char *ptr; // Construct working linked list, if not already made if( ListStatus.first == NULL ) { // This is our first time adding, so let's setup the first pointer // Just in case allocation screws up, we have a decoy ListStatus.decoy = malloc( 1 * sizeof( *ListStatus.decoy ) ); if( !ListStatus.decoy ) { puts( "Allocation failure" ); return; } ListStatus.first = ListStatus.decoy; ListStatus.curr = ListStatus.first; } else { // This is our ++1 time running, prepare to add to the previous current branch ListStatus.decoy = malloc( 1 * sizeof( *( ListStatus.decoy ) ) ); if( !ListStatus.decoy ) { puts( "Allocation failure" ); return; } ListStatus.curr->next = ListStatus.decoy; ListStatus.curr = ListStatus.curr->next; } // Prepare the database for input if( ( fdb = fopen( "database.txt", "a+" ) ) == NULL ) { puts( "Can't open database for editing" ); return; } // Enter a name; remove newlines when necessary printf( "Enter name: " ); if( fgets( ListStatus.curr->name, sizeof( ListStatus.curr->name ), stdin ) != NULL ) if( ( ptr=strchr( ListStatus.curr->name, '\n' ) ) != NULL ) *ptr='\0'; printf( "Enter SS: " ); if( fgets( ListStatus.curr->SS, sizeof( ListStatus.curr->SS ), stdin ) != NULL ) if( ( ptr=strchr( ListStatus.curr->SS, '\n' ) ) != NULL ) *ptr='\0'; // Write the name/SS to the database fwrite( ( void* )( ListStatus.curr ), sizeof( *( ListStatus.curr ) ), 1, fdb); // Close the file pointer to the database fclose( fdb ); } // List all of the data in the linked list void listAll( void ) { // Make sure the linked list is not empty if( ListStatus.first == NULL ) { puts( "No data to list" ); return; } // ptr = Cycles through all of the linked list // c = Keeps track of what part of the list we're on struct mendel *ptr = ListStatus.first; int c=1; // Output the whole linked list do { printf( "# %d:\n" "%s\n" "%s\n" "------\n", c++, ptr->name, ptr->SS ); } while( ( ptr=ptr->next ) != NULL ); }
Don't make me point you to the FAQ:If you are using string functions such as strchr, you should #include <string.h>.Code:char c; /* ... */ while( c = getchar( ) )
If you are using C99, it would be worth mentioning. C90 is still the reigning implementation:Code:void listAll( void ) { // Make sure the linked list is not empty if( ListStatus.first == NULL ) { puts( "No data to list" ); return; } // ptr = Cycles through all of the linked list // c = Keeps track of what part of the list we're on struct mendel *ptr = ListStatus.first;
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.*
Next time Dave, next time you won't find any errors, and I'll be scott free! lol
Gah!
Code:int getchar( void );Code:void listAll( void ) { // Make sure the linked list is not empty if( ListStatus.first == NULL ) { puts( "No data to list" ); return; } // ptr = Cycles through all of the linked list // c = Keeps track of what part of the list we're on struct mendel *ptr = ListStatus.first; // <-- What's wrong with this?
It is either C99 or C++ to declare a variable after a statement. If it's C++, it's off-topic here; if it's C99, it is worth mentioning.Code:struct mendel *ptr = ListStatus.first; // <-- What's wrong with this?
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.*
Thank you Dave, I'll write that on my board...God bless C!
<gesture deleted by Salem>