Thread: Suggestions on a bit of FILE I/O anyone??

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    46

    Question Suggestions on a bit of FILE I/O anyone??

    Ok me n 2 friends have been working on a lil project, its supposed to be like a multiple choice examination thing. Codes have been working perfectly fine, but we have a question on structures and FILE I/O, by the way we are all beginers. We have been pulling questions from a text file and storing the data into structures, it works fine. The next thing was though, we were supposed to print out all the questions the user got wrong, we used a tmp file to store this data, But now we ran into a problem we are supposed to do this until the user says he doesnt want to take all the wrong questions again. So evertime the user gets wrong answers we print it out, and ask them do u want to take the wrong questions again this is supposed to happen until the user has gotten all correct or says i dnt want to take it again. But the approach we have taken is a bit tricky cuz we are assumin we need two tmp files and later it wnt be overwritten cuz the tmps are destroyed till the program exits. Any ideas would be welcome, or other approaches. The codes are below:
    Last edited by blondie.365; 10-20-2008 at 01:51 PM.

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Because I am tired and dripping snot all over my keyboard. I am going to forego reading the bulk of your question as well as completely ignore your code.

    I think the question is:

    I format my file like this: 1.What is a bird?;A.mamal;B.Bird;C.Amphibian;D.Reptile;B;
    How do I parse it to:

    Code:
    struct question {
           char quest [100];
           char a [50];
           char b[50];
           char c[50];
           char d[50];
           char ans[2];
           char complete[250];
           };
    I would first recommend just altering the way you store the file to begin with to this:

    What is a bird?;mamal;Bird;Amphibian;Reptile;B;

    But that is just me. I will just answer the question as if you were an employer with a retarded format that I had to stick to:

    Example:
    Code:
    struct question {
      char quest [100];
      char choice[4][50];
      char ans; // that doesn't need to be an array
      // char complete[250];  <- what is this even for?
    };
    
    /* This function will probably need to be modified for your needs. But this is just an example :) */
    size_t parse_questions(FILE *input, struct question **pool)
    {
      size_t cnt = 0, i;
      struct question *array;
      char buffer[256], *p;
    
      if(!pool || !infile)
        return 0;
    
      fseek(input, 0, SEEK_SET);
      while(fgets(buffer, sizeof(buffer), input))
        ++cnt;
    
      array = malloc(sizeof(*array) * cnt);
      if(!array)
        return 0;
    
      *pool = array;
      fseek(input, 0, SEEK_SET);
    
      while(fgets(buffer, sizeof(buffer), input))
      {
        /* I am not doing a loop here for simplicity's sake if you decide to reformat your
         * file as I suggested.
         */
     
        if((p = strtok(buffer, ";")))
          strncpy(array->quest, p, sizeof(array->quest));
        else
          *array->quest = 0;
    
        for(i = 0; i < 4; ++i)
          if((p = strtok(NULL, ";")))
            strncpy(array->choice[i], p, sizeof(*array->choice));
          else
            *array->choice[i] = 0;
    
        if((p = strtok(NULL, ";")))
          array->ans = *p
        else
          array->ans = 0;
    
        ++array;
      }
    
      return cnt;
    }
    Don't forget to free after you are done!
    Last edited by master5001; 10-20-2008 at 12:47 PM. Reason: I added more error resist lines of code

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Whenever using strtok, you should check if the result is NULL before passing it to strcpy or some such function.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    As noted in the comment that you opted not to read.

    [edit]Oh wait... Nevermind. That was probably blanketed over to me, but definitely directed at the OP. Sorry[/edit]

    In my code, you would simply do something like this:

    Code:
        char *p; // <--= declare this somewhere
    
        if((p = strtok(buffer, ";")))
          strncpy(array->quest, p, sizeof(array->quest));
        else
          *array->quest = 0;
    
        for(i = 0; i < 4; ++i)
          if((p = strtok(NULL, ";")))
            strncpy(array->choice[i], p, sizeof(*array->choice));
          else
            *array->choice[i] = 0;
    
        if((p = strtok(NULL, ";")))
          array->ans = *p
        else
          array->ans = 0;
    Last edited by master5001; 10-20-2008 at 12:47 PM.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    46
    Quote Originally Posted by master5001 View Post
    Because I am tired and dripping snot all over my keyboard. I am going to forego reading the bulk of your question as well as completely ignore your code.

    I think the question is:

    I format my file like this: 1.What is a bird?;A.mamal;B.Bird;C.Amphibian;D.Reptile;B;
    How do I parse it to:

    Code:
    struct question {
           char quest [100];
           char a [50];
           char b[50];
           char c[50];
           char d[50];
           char ans[2];
           char complete[250];
           };
    [/code]

    Don't forget to free after you are done!
    NO the parsing is done ok, my question was for simplicity how would i print over the question they got wrong over and over until they get it correct. The code above is well, i know bit long and unprofessional but we are beginners o and the char complete[250] was to store teh entire question array so that i could later be printed to the tmpfile which over prints the wrong questions

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    46
    Quote Originally Posted by master5001 View Post
    As noted in the comment that you opted not to read.

    [edit]Oh wait... Nevermind. That was probably blanketed over to me, but definitely directed at the OP. Sorry[/edit]

    In my code, you would simply do something like this:

    Code:
        char *p; // <--= declare this somewhere
    
        if((p = strtok(buffer, ";")))
          strncpy(array->quest, p, sizeof(array->quest));
        else
          *array->quest = 0;
    
        for(i = 0; i < 4; ++i)
          if((p = strtok(NULL, ";")))
            strncpy(array->choice[i], p, sizeof(*array->choice));
          else
            *array->choice[i] = 0;
    
        if((p = strtok(NULL, ";")))
          array->ans = *p
        else
          array->ans = 0;
    Lol, hey anyway i think the best way might be for me to go and read over structures cause im kinda new to them, hence, the code above bit confusing lol

  7. #7
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Ok... If you were to use your code it could prove difficult and require using tempfiles or something. If you use my way you can simply add one extra bit of information to the structure.

    Example:
    Code:
    struct question {
      char quest [100];
      char choice[4][50];
      char ans; // that doesn't need to be an array
      // char complete[250];  <- what is this even for?
      char correct;
    };
    
    /* This function will probably need to be modified for your needs. But this is just an example :) */
    size_t parse_questions(FILE *input, struct question **pool)
    {
      size_t cnt = 0, i;
      struct question *array;
      char buffer[256], *p;
    
      if(!pool || !infile)
        return 0;
    
      fseek(input, 0, SEEK_SET);
      while(fgets(buffer, sizeof(buffer), input))
        ++cnt;
    
      array = malloc(sizeof(*array) * cnt);
      if(!array)
        return 0;
    
      *pool = array;
      fseek(input, 0, SEEK_SET);
    
      while(fgets(buffer, sizeof(buffer), input))
      {
        /* I am not doing a loop here for simplicity's sake if you decide to reformat your
         * file as I suggested.
         */
     
        if((p = strtok(buffer, ";")))
          strncpy(array->quest, p, sizeof(array->quest));
        else
          *array->quest = 0;
    
        for(i = 0; i < 4; ++i)
          if((p = strtok(NULL, ";")))
            strncpy(array->choice[i], p, sizeof(*array->choice));
          else
            *array->choice[i] = 0;
    
        if((p = strtok(NULL, ";")))
          array->ans = *p
        else
          array->ans = 0;
    
        array->correct = 0;
        ++array;
      }
    
      return cnt;
    }
    
    int ask_question(struct question *q)
    {
      int i;
    
      if(!q)
        return 0;
    
      if(q->correct)
        return 1;
    
      fputs(q->quest, stdout);
      for(i = 0; i < 4; ++i)
        fputs(q->choice[i]);
    
      i = getchar();
    
      if(i == q->ans)
        q->correct = 1;
    
      return q->correct;
    }
    
    int main(void)
    {
      FILE *file = fopen("whatever.txt", "r");
      struct quesiton *q;
      size_t i, count, correct;
    
      if(file)
      {
        count = parse_questions(file, &q);
    
        while(correct < count)
          for(i = 0, correct = 0; i < count; ++i)
            correct += ask_question(q + i);
    
        free(q);
        fclose(file);
      }
    
      return 0;
    }

  8. #8
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Quote Originally Posted by blondie.365 View Post
    Lol, hey anyway i think the best way might be for me to go and read over structures cause im kinda new to them, hence, the code above bit confusing lol
    Just refer to my last post. I think that does it better than how you are trying to do it (alas, I had to break down and actually read your code).

    I think it would be more interesting to lose the hard-coded A, B, C, and D's as well as the hard coded question numbers. By doing that, you could totally have random order to the question as well as mix up the answers.

    [question-id];[question];[answer-id];[answer];[answer-id];[answer];[answer-id];[answer];[answer-id];[answer];[correct-answer-id];
    Last edited by master5001; 10-20-2008 at 01:04 PM.

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    46
    Quote Originally Posted by master5001 View Post
    Just refer to my last post. I think that does it better than how you are trying to do it (alas, I had to break down and actually read your code).

    I think it would be more interesting to lose the hard-coded A, B, C, and D's as well as the hard coded question numbers. By doing that, you could totally have random order to the question as well as mix up the answers.

    [question-id];[question];[answer-id];[answer];[answer-id];[answer];[answer-id];[answer];[answer-id];[answer];[correct-answer-id];
    Hey Master5001 thanks for the insight on structures like i said ill go home and read on it, ill look at your codes maybe change my entire way im doin the coding and start over from scrtach cuz i thnk the way it is is a bit wordy and unecessary, yea as u can see its a quiz im trying to do. Has one question and four possible answers. Thank you for your time, hopefully this program is done by wednesday, lol

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    46
    Quote Originally Posted by master5001 View Post
    Just refer to my last post. I think that does it better than how you are trying to do it (alas, I had to break down and actually read your code).

    I think it would be more interesting to lose the hard-coded A, B, C, and D's as well as the hard coded question numbers. By doing that, you could totally have random order to the question as well as mix up the answers.

    [question-id];[question];[answer-id];[answer];[answer-id];[answer];[answer-id];[answer];[answer-id];[answer];[correct-answer-id];
    Hey Master5001 by the way u said refer to my last post, did that mean u posted on something similar to this, if u did how do i go to it. I tried clickin on ur user name but it said i dnt have privilges to view or soemthing like that.

  11. #11
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    I don't think deleting your code was necessary. There was nothing wrong with where you started. I think its easier to keep things in a way that can be managed. That said, keeping stuff in memory when possible is always a plus. And yeah, my code goes through the entire file twice in order to parse it, however think of it this way, Its a small price to pay in order to have everything allocated directly into memory so that you can refer back to a previous question without needing to open a second file just to store the questions the user got wrong.

    Elysia is going to probably shank me if she reads your objective, then my code, then realizes I was being far too forthcoming with direct answers.... I didn't realize it was homework, for the record. I guess that is the tragic downfall behind seeing a huge block of code, and a lengthy question and not wanting to really read too much into either.

  12. #12
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Quote Originally Posted by blondie.365 View Post
    Hey Master5001 by the way u said refer to my last post, did that mean u posted on something similar to this, if u did how do i go to it. I tried clickin on ur user name but it said i dnt have privilges to view or soemthing like that.
    I was saying refer to this post. You need to post like 10 times to be able to have that privilege, I believe.

  13. #13
    Registered User
    Join Date
    Oct 2008
    Posts
    46
    Quote Originally Posted by master5001 View Post

    Elysia is going to probably shank me if she reads your objective, then my code, then realizes I was being far too forthcoming with direct answers.... I didn't realize it was homework, for the record. I guess that is the tragic downfall behind seeing a huge block of code, and a lengthy question and not wanting to really read too much into either.

    Lol dw i do have my standards not gona copy and paste ur work, besides that code is far too advanced for me lol, I'll probably end up tryint to do something with what i have. So Elysia no worries dnt go punishing master, by the way master5001 thanks for writing on the thread ur like the only one, lol, guess the question was too wordy. Oh by the way teacher tracks us, so if id use the code he'd know
    Last edited by blondie.365; 10-20-2008 at 01:29 PM.

  14. #14
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Well if he invests his time looking at the code a sick software engineer writes into a forum box without testing it in any way, he can surely be my guest. I will autograph a tissue box just for him.

    I like to answer with examples, which isn't the most popular format. Though, I am getting better about not just giving out freebies. You had a VERY functional program already posted. Most of us tend to like quick easy to answer questions. A lot of code, or a lot of question usually results in a lack of response. That is why my first response was so far off base. I didn't read much other than your file format and just assumed what you needed from there. The code was not the issue. Feel free to keep posting code like you did, just make your questions more direct.

    I never respond like:

    Greetings blondie.365,

    My name is Matt. I am a software engineer who is doing is pre-med studies. Me and some of the other programmers here were just looking around the forum and spotted your question. Since I hate when tabstop and matsp beat me to a post, I rushed out an answer as fast as possible. Which wasn't as fast as it would have been had I not been sick, but I did rewrite your whole program---etc. A lot of us just ignore back story.

  15. #15
    Registered User
    Join Date
    Oct 2008
    Posts
    46
    Quote Originally Posted by master5001 View Post
    Well if he invests his time looking at the code a sick software
    I never respond like:

    Greetings blondie.365,

    My name is Matt. I am a software engineer who is doing is pre-med studies. Me and some of the other programmers here were just looking around the forum and spotted your question. Since I hate when tabstop and matsp beat me to a post, I rushed out an answer as fast as possible. Which wasn't as fast as it would have been had I not been sick, but I did rewrite your whole program---etc. A lot of us just ignore back story.
    Lol, i understand you ill be more specific next time. So ull see if the prof gets in here lol, so awesome software engineer and doin pre-med way ota go, so awesome.Couple years from now i hope im like u, C will be like my native language lol. But ya thanks for the help and insight, i see tabstop and matsp lol, competition ehh, so yup ill look at my program and see what i can do ill take ur suggestions bout keeping the questions on memory etc etc, which like i said will do my reading tonight!!

    Thank U!!

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. Question about file I/O from a newbie
    By henrik in forum C Programming
    Replies: 4
    Last Post: 11-13-2007, 12:48 AM
  3. File I/O Question
    By Achy in forum C Programming
    Replies: 2
    Last Post: 11-18-2005, 12:09 AM
  4. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  5. Replies: 3
    Last Post: 03-04-2005, 02:46 PM