Thread: Need help; stuck with this; read file + compare with user input

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    13

    Need help; stuck with this; read file + compare with user input

    Hi all,

    I'm stuck with another problem.
    I'm trying to make a multiple choice quiz.

    Each question has 2 answers, one of them is the right one (A or B).

    The questions + answers are stored in a .txt file like this;

    What is football?;A car;A game;B

    Now i want my code to stop showing the line at

    What is football?;A car;A game

    and let the user input A or B, then compare with the last character of the line in my file, which is ;A or ;B.

    Here's my code;

    Code:
    void spelen(void)
    
    
    {
       static const char filename[] = "vragen.txt"; /* the name of a file to open */
       FILE *file = fopen(filename, "r+"); /* try to open the file */
       if ( file )
       {
          char line[BUFSIZ]; /* space to read a line into */
          int k = 0;
          while ( fgets(line, sizeof line, file) ) /* read each line */
          {
             int i;
             char *token = line; /* point to the beginning of the line */
             printf("line %d:\n", ++k);
             for ( i = 0; *token; ++i ) /* loop through each character on the line */
             {
                /* search for delimiters */
                size_t len = strcspn(token, ";\n"); 
                /* print the found text: use *.* in format to specify a maximum print size */
                printf("[%2d] = \"%*.*s\"\n", i, (int)len, (int)len, token);
                 /* advance pointer by one more than the length of the found text */
                token += len + 1;
             }
          }
          fclose(file);
       }
    
    }
    and here's my output:

    Code:
    [0]What is football?
    [1]A car
    [2]A game
    [3]B
    Any advice, tips or help with this would be great.

    Thanks in advance

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
    struct quiz {
      char question[100];
      char answers[2][100];
      char correct;
    };
    Create an array of those, and fill in with details from the file.

    Then pick random entries from that array, printing the question and two answers, then read and compare the user input.
    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.

  3. #3
    Registered User
    Join Date
    Jan 2007
    Posts
    13
    How can i copy the details (from the file);

    Code:
    What is football;A game; A car; A
    to this structure?
    Code:
    struct quiz {
       char question[100];         (What is a football)
       char answers[2][100];     (A game)(A car)                                       
       char correct;                     (A)

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    read line
    then parse it using one of the methods suggested in the thread
    http://cboard.cprogramming.com/showt...strtok+parsing
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Jan 2007
    Posts
    13
    well i tried with this but still can't figure it out.. :

    Code:
    struct vragen {   
    	 char vraag[MAXVRAAG];
    	 char  antw[MAXANTW];
    	 char  antw1[MAXANTW];
    	 char  keuze[2];
    };
    Code:
    void spelen(void)
    
    
    {
       static const char filename[] = "vragen.txt"; /* the name of a file to open */
       FILE *file = fopen(filename, "r+"); /* try to open the file */
       if ( file )
       {
          char line[BUFSIZ]; /* space to read a line into */
          int k = 0;
          while ( fgets(line, sizeof line, file) ) /* read each line */
          {
             sscanf(vragen, "%s %s %s %s",
             vragen.vraag,
             vragen.antw,
             vragen.antw1,
             vragen.keuze);
          }
          fclose(file);
       }
       printf("%s", vragen.vraag)
    }

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    your solution is good for the space separated words

    in your case you have strings separated by ;
    the noted thread has examples how to parse such type of strings. Have you read all the thread?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User
    Join Date
    Jan 2007
    Posts
    13
    Quote Originally Posted by vart
    your solution is good for the space separated words

    in your case you have strings separated by ;
    the noted thread has examples how to parse such type of strings. Have you read all the thread?
    Yes vart i did,

    when i compile i get these errors:

    Code:
    In function `void spelen()': 
    expected primary-expression before '.' token 
     expected primary-expression before '.' token 
     expected primary-expression before '.' token 
     expected primary-expression before '.' token 
    expected primary-expression before '.' token 
     expected `;' before '}' token
    and i changed my code to this after reading the thread you suggested me;
    Code:
    {
       static const char filename[] = "vragen.txt"; /* the name of a file to open */
       FILE *file = fopen(filename, "r+"); /* try to open the file */
       if ( file )
       {
          char line[BUFSIZ]; /* space to read a line into */
          int k = 0;
          while ( fgets(line, sizeof line, file) ) /* read each line */
          {
             sscanf(line, "%[^ ]%[^;];%[^;];%[^;]",
             vragen.vraag,
             vragen.antw,
             vragen.antw1,
             vragen.keuze);
          }
          fclose(file);
       }
    Last edited by barrie; 01-04-2007 at 01:27 PM.

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you haven't defined a variable of type struct vragen
    I think you should define array of structs in the calling function
    and pass it as an argument to the spelen function
    also in your while loop you should iterate through the array to fill new struct on each iteration
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User
    Join Date
    Jan 2007
    Posts
    13
    Quote Originally Posted by vart
    you haven't defined a variable of type struct vragen
    I think you should define array of structs in the calling function
    and pass it as an argument to the spelen function
    also in your while loop you should iterate through the array to fill new struct on each iteration
    i don't quite get this, could you give me an example?

    thanks in advance

  10. #10
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    something like
    Code:
    int main()
    {
    	struct vragen quiz[100];
    	spelen(quiz,100);
    }
    
    void spelen(struct vragen* quiz, int maxQ)
    {
    	int index = 0;
    	...
    	while ( fgets(line, sizeof line, file) ) /* read each line */
          {
             sscanf(vragen, "%s %s %s %s",
             quiz[i].vraag,
             quiz[i].antw,
             quiz[i].antw1,
             quiz[i].keuze);
    		 i++;
    		 if(i == maxQ)
    			 break;
          }
    ...
    }
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well if the lines are on 4 separate lines, then you need 4 fgets() calls, followed by 4 lines to extract data and store in the structure.
    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.

  12. #12
    Registered User
    Join Date
    Jan 2007
    Posts
    13
    Quote Originally Posted by vart
    something like
    Code:
    int main()
    {
    	struct vragen quiz[100];
    	spelen(quiz,100);
    }
    
    void spelen(struct vragen* quiz, int maxQ)
    {
    	int index = 0;
    	...
    	while ( fgets(line, sizeof line, file) ) /* read each line */
          {
             sscanf(vragen, "%s %s %s %s",
             quiz[i].vraag,
             quiz[i].antw,
             quiz[i].antw1,
             quiz[i].keuze);
    		 i++;
    		 if(i == maxQ)
    			 break;
          }
    ...
    }
    Thanks vart, this works like a charm!
    You gave me the insight, thanks for your time & effort!

    If someone is wondering; I changed my code to:

    Code:
     struct vragen quiz[100]; 
       int i;   
       static const char filename[] = "vragen.txt"; /* the name of a file to open */
       FILE *file = fopen(filename, "r+"); /* try to open the file */
       if ( file )
       {
          char line[BUFSIZ]; /* space to read a line into */
          int i = 0;
          while ( fgets(line, sizeof line, file) ) /* read each line */
          {
             sscanf(line, "%[^]%[^;];%[^;];%[^;]",
             quiz[i].vraag,
             quiz[i].antw,
             quiz[i].antw1,
             quiz[i].keuze);
             i++;
             if(i == MAXVRAAG) break;
          }
          fclose(file);

  13. #13
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    what is the MAXVRAAG constant?
    I thought it was used in the

    char vraag[MAXVRAAG];

    to determine the longets question?
    Then using it in the loop is out of place
    You should use another const QUIZ_COUNT and use it in two place - where you declare the array
    struct vragen quiz[QUIZ_COUNT];
    and where you check that there is no memory overrun
    if(i == QUIZ_COUNT ) break;
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #14
    Registered User
    Join Date
    Jan 2007
    Posts
    13
    Quote Originally Posted by vart
    what is the MAXVRAAG constant?
    I thought it was used in the

    char vraag[MAXVRAAG];

    to determine the longets question?
    Then using it in the loop is out of place
    You should use another const QUIZ_COUNT and use it in two place - where you declare the array
    struct vragen quiz[QUIZ_COUNT];
    and where you check that there is no memory overrun
    if(i == QUIZ_COUNT ) break;
    MAXVRAAG is from

    #define MAXVRAAG 30

    and used for the maximum amount of characters in a question (char vraag[MAXVRAAG]).

    I've made another const though, MAX 30, and used MAX for the loop, is this ok?

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Use expressive names for all your tokens, including macros. MAX could mean anything. QUEST_COUNT was better.

    edit: In fact
    Code:
    #define MAXVRAAG      30UL
    #define QUEST_COUNT   MAXVRAAG
    is probably best, in case you change MAXVRAAG at a later date. QUEST_COUNT will never need to be updated.
    Last edited by whiteflags; 01-04-2007 at 03:14 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  3. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. c script help to read a file & update
    By indy in forum C Programming
    Replies: 8
    Last Post: 12-01-2003, 11:32 AM