Thread: Can someone please help deadline tomorow

  1. #16
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by scott1990 View Post
    Is tmp some sort of function? MK27
    No, it's an instance of this datatype:

    Code:
    typedef struct
    {
      char ISBN[20];
      char Author[SIZE];
      char Title[SIZE];
    }record_structure;
    You only need one, you are going to overwrite it at each iteration of the while loop. However, there is a mistake in that code I posted [corrected] -- since tmp is not a pointer you need to use the & address of operator:
    Code:
    while (fread(&tmp, sizeof(record_structure), 1, record_file)) {
    You picked kind of an unfortunate day to look for advice here -- everyone is probably out enjoying the holiday and totally gorgeous weather on the eastern seaboard.

    On the bright side, as Adak says, presuming the rest of your code compiles and works, you are perhaps not far from being done. I'll probably be in and out all night, don't give up. The more information and explanation you can provide in this case the better.

    If your existing code does not compile and work -- well, this is going to be a "learning the hard way" kind of lesson, which you should take to heart because to err is human, but learning the hard way is human too and don't miss out on that.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #17
    Registered User
    Join Date
    May 2010
    Posts
    24

    Talking

    Luckily for me the rest of the program compiles and works(not great but its passable).
    I've compiled this but all it does is ask me to enter the title and nothing else so im on the losing path here but i wont give up lol you've inspired me to see this through MK27
    thanks!

    Now what am i doing wrong here? i know i haven't implemented error handling yet but i will do that.

    Code:
    void search_by_title()
    {
    	system("cls");
        
        printf ("Please enter the title of the book you are searching for: ");
        scanf("%s", &searchtitle);
        
        record_file = fopen("C:\\bookfile.bin","rb");
        
         while (fread(&tmp,sizeof(record_structure),1,record_file))
         if (strcmp(searchtitle,tmp.Title) == 0){
    
       printf("\n Title\t\t Author\t\t ISBN ");
       printf("\n %4i %-30s %s",num_records,record_array[num_records].ISBN,
       record_array[num_records].Author,record_array[num_records].Title);	
    }
      
       screen_pause();
       num_records++;
       fclose(record_file);
    }

  3. #18
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >> Now what am i doing wrong here?

    I can think of one thing.

    >> scanf("%s", &searchtitle);

    Aren't most real book titles more than one word? That will be a problem if your user intends to find, The Old Man and the Sea, and the computer only looks for The book title!

    But that's not even the worst of it. The variable searchtitle isn't defined yet, but I can guess what it should be. &searchtitle is a completely different kind of argument to scanf. You're pointing to a string (char **, not what I would guess as the correct type, char *). As you found out in class I hope the name of an array decays to a pointer to the first element in pointer context.

    Arrays are frequently used in pointer context, so it's important to know you need that extra star or &.

    If the call were like this:

    scanf ("%s" , searchtitle);

    It would work to an extent. You'd be vulnerable to a user typing too long of a title, but I see you know what field widths are, from your other bits of code.

  4. #19
    Registered User
    Join Date
    May 2010
    Posts
    24
    Hi whiteflags thanks for your input, ive took away '&' from the scanf but when i compile it still does the same thing, it only asks for the user to enter the title and when i do nothing happens.

  5. #20
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by scott1990 View Post
    I've compiled this but all it does is ask me to enter the title and nothing else
    Unfortunately, while using a non-human readable data file is easier in some ways, debugging it's use is probably harder. But don't worry, we can probably figure out if that is the complication (if the rest of your code works, it probably isn't so serious).

    Quote Originally Posted by whiteflags View Post
    I can think of one thing.

    >> scanf("%s", &searchtitle);

    Aren't most real book titles more than one word? That will be a problem if your user intends to find, The Old Man and the Sea, and the computer only looks for The book title!
    I always forget this point until I notice the outcome. @scott: this could have significant consequences for the way your original data is inputted -- scanf's %s reads up to whitespace -- and relates to what I just said about the difficulties debugging a non-human readable data file.

    _______

    I think you have fundamentally misunderstood some of the basic logic too, hopefully we can work that out. Here's more what the search should look like:

    Code:
    void search_by_title() {
    	record_array tmp;
    
    	printf ("Please enter the title of the book you are searching for: ");
    	scanf("%[^\n]%*c", &searchtitle);
    
    	record_file = fopen("C:\\bookfile.bin","rb");
    
    	while (fread(&tmp,sizeof(record_structure),1,record_file)) {
    		fprintf(stderr, "---> %s ||||| %s ||||| %s <---\n", tmp.Title, tmp.Author, tmp.ISBN);
    		if (strcmp(searchtitle,tmp.Title) == 0)
    			printf("Title: %s Author %s ISBN %s\n", tmp.Title, tmp.Author, tmp.ISBN);
    	}
    	fclose(record_file);
    }
    Have a look at the red parts and try and think about why I think these are important for you to consider, they involve some critical changes involving that "basic logic" (fclose is kind of a style point but a very important one).

    The green line is a "debugging" line that you'll want to remove later. The point is to make sure your data is okay.

    The purple bit is a solution to the problem whiteflags pointed out.

    I think there are a number of possible problems you're about to run into but don't panic, just ask questions, I can't really go into depth on everything...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #21
    Registered User
    Join Date
    May 2010
    Posts
    24
    Well i've compiled that code(thanks for your time) with no errors but when i press option 3 to get into it it just stays on the menu screen which is confusing as i dont know why thats happening.

    The only thing i had to change was record_array tmp; as it wouldnt compile with that so i changed it to record_structure tmp; which succesfully compiled, i dont know if i should have changed it or not probably not my bad.

  7. #22
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by scott1990 View Post
    The only thing i had to change was record_array tmp; as it wouldnt compile with that so i changed it to record_structure tmp; which succesfully compiled, i dont know if i should have changed it or not probably not my bad.
    Yeah, whoops again. Post your entire code as it exist now.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #23
    Registered User
    Join Date
    May 2010
    Posts
    24
    This is what i've got so far MK27

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define SIZE 30
    /* global variables */			
    typedef struct
    {
      char ISBN[20];
      char Author[SIZE];
      char Title[SIZE];
    }record_structure;  
    
    FILE *record_file;
    int choice;
    record_structure record_array[8];
    int num_records;
    int searchresult;
    char searchtitle[SIZE];
    
    
    /* function prototypes */
    void intro();
    void menu();
    void close();
    void add_book();
    void option2();
    void search_by_title();
    void display_all_records();
    void screen_pause();
    
    /*******************************************************************************************/
    
    int main()
    {
    	intro();
    	do
    	{
    		menu();
    	}
    	while (choice!=5);
    	close();
        return 0;
    }
    
    /*******************************************************************************************/
    
    void intro()
    {
    	system("cls");
    	printf("\n\n\n\n\n\n\tWelcome to Forth Valley's Collection of Technical Books");
    	screen_pause();
    }
    
    /*******************************************************************************************/
    
    void add_book()
    {
    	record_file = fopen("C:\\bookfile.bin","wb");
        
        system("cls");
        
        printf( "\n\nAdd book details");
        
        for(num_records=0;num_records<=7;num_records++)
             {
               printf( "\n\nISBN: ");
               fflush(stdin);
               fgets(record_array[num_records].ISBN, 20, stdin);
               printf( "\n\nAuthor: ");
               fflush(stdin);
               fgets(record_array[num_records].Author, SIZE, stdin);
               printf( "\n\nTitle: ");
               fflush(stdin);
               fgets(record_array[num_records].Title, SIZE, stdin);
               printf( "------------------------------------" );
               
               fwrite(&record_array[num_records],sizeof(record_structure),1,record_file);
             
              } 
               printf( "\n\nYou have succesfully inputed the details of 8 books" );
               fclose(record_file);
        
        screen_pause();
    }
    
    /*******************************************************************************************/
    
    void option2()
    {
    	system("cls");
    	printf("Search for ISBN ");
    	screen_pause();
    }
    
    /*******************************************************************************************/
    
    void search_by_title()
    {
        
        record_structure tmp;
    	
    	printf ("Please enter the title of the book you are searching for: ");
    	scanf("%[^\n]%*c", &searchtitle);
    
    	record_file = fopen("C:\\bookfile.bin","rb");
    
    	while (fread(&tmp,sizeof(record_structure),1,record_file)) {
    		fprintf(stderr, "---> %s ||||| %s ||||| %s <---\n", tmp.Title, tmp.Author, tmp.ISBN);
    		if (strcmp(searchtitle,tmp.Title) == 0)
    			printf("Title: %s Author %s ISBN %s\n", tmp.Title, tmp.Author, tmp.ISBN);
    	}
    	fclose(record_file);
    
    }
    
    /*******************************************************************************************/
    
    void display_all_records()
    {
    	record_file = fopen("C:\\bookfile.bin","rb");
        
        system("cls");
        
        printf("\n\t\t\tDetails of all books");
    	printf("\n\n\n ID NO\t\tISBN\t\t\tAuthor\t\t\tTitle");
    	
    	num_records=0;
    	fread(&record_array[num_records],sizeof(record_structure),1,record_file);
    	
    	while(!feof(record_file))
    	{	
    		printf("\n%3i %21s %47s %79s ",num_records,record_array[num_records].ISBN,
    			record_array[num_records].Author,record_array[num_records].Title);
    		fflush(stdin);
    		num_records++;
    		fread(&record_array[num_records],sizeof(record_structure),1,record_file);
    	}
    	
    	screen_pause();
    	
        fclose(record_file);
    }
    
    /*******************************************************************************************/
    
    void close()
    {
    	system("cls");
    	printf("\n\n\n\n\n\n\tThank you for using this program");
    	screen_pause();
    }
    
    /*******************************************************************************************/
    
    void menu()
    {
    	system("cls");
    	printf("\n\nMENU");
    	printf("\n\n1 - Add new entry: ");
    	printf("\n2 - Book search by ISBN: ");
    	printf("\n3 - Book search by title: ");
    	printf("\n4 - Show details off all books stored: ");
    	printf("\n5 - Exit Program:");
    	
        printf("\n\nEnter your choice ");
        scanf("%i", &choice);
        while((choice<1)||(choice>5))
        {
         printf("\n\nYou eneterd an invalid number please enter a valid number");
         printf("\n\n\tEnter your choice: ");
         scanf("%i", &choice);
         }
           
    	switch(choice)
    	{
    		case 1 : add_book();break;
    		case 2 : option2(); break;
    		case 3 : search_by_title(); break;
    		case 4 : display_all_records() ; break;
    		case 5 :  break;
    	}
    }
    
    /*******************************************************************************************/
    
    void screen_pause()
    {
    	printf("\n\n\tPress any key to continue.....");
    	getch();
    }

  9. #24
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    It's because of that newline issue pointed out by whiteflags. Because you use fgets to store read the data in, the scanf %s whitespace thing is not an issue. However, fgets will include the newline, so it's still there.

    You might notice that your "Show details off all books stored" data displays with an odd stagger to it:
    Code:
     ID NO		ISBN			Author			Title
      0                    1
                                                jan
                                                                          title one
     
      1                    2
                                               hula
                                                                          title two
     
      2                    3
                                                oct
                                                                        title three
    See the newlines? "jan\n" != "jan" for strcmp.

    I added this function to remove those:
    Code:
    void remove_newline (char *str) {
    	char *p = strrchr(str,'\n');
    	*p = '\0';
    }
    and used it in add_book() like this:
    Code:
        for(num_records=0;num_records<=2; num_records++)
             {
               printf( "\n\nISBN: ");
               fflush(stdin);
               fgets(record_array[num_records].ISBN, 20, stdin);
    		   remove_newline(record_array[num_records].ISBN);
               printf( "\n\nAuthor: ");
               fflush(stdin);
               fgets(record_array[num_records].Author, SIZE, stdin);
    		   remove_newline(record_array[num_records].Author);
               printf( "\n\nTitle: ");
               fflush(stdin);
               fgets(record_array[num_records].Title, SIZE, stdin);
    		   remove_newline(record_array[num_records].Title);
    Now, the display is more like this:

    Code:
     ID NO		ISBN			Author			Title
      0 		1 			jan 			title one 
      1 		2 			hula 			title two 
      2 		3 			oct 			title three
    Altho I had to change some formatting in display_all_records too:
    Code:
        printf("\n\t\t\tDetails of all books");
    	printf("\n\n\n ID NO\t\tISBN\t\t\tAuthor\t\t\tTitle");
    Now, when I do the search I get:
    Code:
    Please enter the title of the book you are searching for: title two
    1 ---> title one ||||| jan ||||| 1 <---
    1 ---> title two ||||| hula ||||| 2 <---
    Title: title two Author hula ISBN 2
    1 ---> title three ||||| oct ||||| 3 <---
    Notice the newlines are gone so both "|||||"s appear on the same line in the debugging output? More importantly, the search finds a target.

    So: you have some far from perfect code but it does work...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #25
    Registered User
    Join Date
    May 2010
    Posts
    24
    Wow thanks for all that MK27 much appreciated. I was stumped on why when it displayed all records it was like that but thanks for explaining. Now i notice you say that the search now works for you but it doesn't for me, did you edit some of the search code after your alterations in the last post? or i think it maybe my compiler, im using Dev-C++.

  11. #26
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    No, it's still the same. I notice there is one small mistake in it tho*; it does not make a difference for me, but it is still a mistake and might lead to "undefined behavior" meaning your compiler might handle this mistake differently:
    Code:
    void search_by_title()
    {
        
        record_structure tmp;
    	
    	printf ("Please enter the title of the book you are searching for: ");
    	scanf("%[^\n]%*c", &searchtitle);
    
    	record_file = fopen("bookfile.bin","rb");
    
    	while ((fread(&tmp,sizeof(record_structure),1,record_file))) {
    //		fprintf(stderr, "%d ---> %s ||||| %s ||||| %s <---\n", tmp.Title, tmp.Author, tmp.ISBN);
    		if (strcmp(searchtitle,tmp.Title) == 0)
    			printf("Title: %s Author %s ISBN %s\n", tmp.Title, tmp.Author, tmp.ISBN);
    	}
    	fclose(record_file);
    
    }
    You should remove the & -- searchtitle is pointer all by itself. A style point here would be that if this is the only place you use it, searchtitle should be local to search_by_title() not global.

    * I think your compiler would have warned you about that one if you had warnings enabled -- I didn't before which is why I just noticed this now...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #27
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I mentioned this several posts ago.

    Quote Originally Posted by whiteflags View Post
    But that's not even the worst of it. The variable searchtitle isn't defined yet, but I can guess what it should be. &searchtitle is a completely different kind of argument to scanf. You're pointing to a string (char **, not what I would guess as the correct type, char *). As you found out in class I hope the name of an array decays to a pointer to the first element in pointer context.

    Arrays are frequently used in pointer context, so it's important to know you need that extra star or &.

    If the call were like this:

    scanf ("%s" , searchtitle);

    It would work to an extent. You'd be vulnerable to a user typing too long of a title, but I see you know what field widths are, from your other bits of code.
    I'm posting it again - for the OP's benefit 'cause apparently it didn't sink in - and cause being ignored by your peers is a real kick in the balls I'm not prepared to deal with maturely this morning.

  13. #28
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by whiteflags View Post
    I'm posting it again - for the OP's benefit 'cause apparently it didn't sink in - and cause being ignored by your peers is a real kick in the balls I'm not prepared to deal with maturely this morning.
    Tch, nobody's ignoring you, this has been dealt with (witness the OP's last posted code uses %[^n]):

    Quote Originally Posted by MK27 View Post
    It's because of that newline issue pointed out by whiteflags.
    Have some coffee.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #29
    Registered User
    Join Date
    May 2010
    Posts
    24
    The search option isnt letting me type in any input, it produces the 8 records instead.

    Here's what it looks like:

    http://i45.tinypic.com/14iisep.jpg

    Oh and i spoke to my lecturer today and he says he'll give me to Thursday to do it

  15. #30
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by scott1990 View Post
    The search option isnt letting me type in any input, it produces the 8 records instead.

    Here's what it looks like:

    http://i45.tinypic.com/14iisep.jpg

    Oh and i spoke to my lecturer today and he says he'll give me to Thursday to do it
    Well, that's good.

    I just noticed I did add something in order to get that to work the first time, but forgot about it by the time I got to that last long post. In menu():
    Code:
        printf("\n\nEnter your choice ");
        scanf("%d%*c", &choice);
    This is to clear the \n, which otherwise will be there waiting. I notice some places you use fflush(stdin) to deal with that. That's an undefined behaviour risk again, and unless you've actually seen your prof use it (s/he shouldn't be, either) s/he won't like it! Read this, it will take you 10 minutes:

    STDIN pitfalls
    Last edited by MK27; 06-01-2010 at 09:39 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed