Thread: Test Scores Program

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    14

    Test Scores Program

    Hi All,

    I believe its going to be a long night. This is a pretty long program (for me) and Im only about 1/2 way thru. Right now Im stuck because somehow one of my variables is getting changed and I cant figure out how. Ive been using this site as a resource for awhile now as I struggle thru my C courses, desperately trying to understand. I knew it was only a matter of time before I turned here for help. So, here goes...

    NOTE: You will see a lot of printf statements that are left justified. These are for debugging. Sorry! But I left them in so it is also easier to tell you where the problem is. Somehow between printf("NumElems6 and printf("NumElems7 my numElems variable is getting changed from 10 to 4. Im using an input file (obviously) and will try to upload it, as I imagine it will probably help you see what is going on.

    Thanks so much in advance for your help!

    Description: Program reads from input file # of test
    answers, correct test answers, Student ID, and student's
    answers, checks to see if student got answer right, and
    then prints the results.


    Code:
    #include<stdio.h>
    
    int readAnswerInfo (FILE *infilep, int numElems);
    int readStudentData(FILE *infilep, int numElems, int answerKeyArray[], int frequencyArray[], FILE *outfilep);
    
    
    int main (void)
    {
        int numElems = -1; /*number of test questions and
                        return variable from readAnswerInfo (function 1)*/
        FILE *infile; /*declares infile as a file variable*/
        FILE *outfile; /*declares outfile as a file variable*/
        int answerKeyArray[] = {0};
        int frequencyArray[] = {0};
    
    printf("NumElems1: %d\n", numElems);
    
        infile=fopen("test_input1.txt", "r");
        if( infile == NULL )
        {
            printf("Input file didn't open\n");
            return 100; //exit main
        } //end
    
    printf("NumElems2: %d\n", numElems);
    
        outfile=fopen("output.txt", "w");
        if(outfile==NULL)
        {
            printf("Output file didn't open\n");
            return 101; //exit main
        } //end
    
    printf("NumElems3: %d\n", numElems);
    
        numElems = readAnswerInfo(infile, numElems);
    
    printf("NumElems4: %d\n", numElems);
    
        if(numElems > 0 || numElems <= 100)
        {
            readStudentData(infile, numElems, answerKeyArray,
                            frequencyArray, outfile);
        }
        else
            printf("Error with input file: input1.txt\n");
    
    printf("\nNumElems8: %d\n", numElems);
    printf("\nAnswer Key: ");
    for( int i = 0; i < numElems ; i++ )
    printf("%d", answerKeyArray[i]);
    
    
        return 0;
    } 
    
    int readAnswerInfo (FILE *infilep, int numElems)
    {
    
        fscanf(infilep,"%d", &numElems);
    printf("NumElems5: %d\n", numElems);
    
        if( numElems > 0 || numElems <= 100 )
            return numElems;
        else
            return 0;
    }
    
    int readStudentData (FILE *infilep, int numElems, int answerKeyArray[], int frequencyArray[], FILE *outfilep)
    {
        int i;
    printf("NumElems6: %d\n", numElems);
    
        for( i = 0; i < numElems ; ++i )
            fscanf(infilep,"%d", &answerKeyArray[i]);
    
    printf("\nNumElems7: %d\n", numElems);
    printf("Answer Key: ");
    for( i = 0; i < numElems ; i++ )
    printf("%d", answerKeyArray[i]);
    
        return 0;
    }
    Attached Files Attached Files

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > int answerKeyArray[]
    C doesn't have self-expanding arrays.
    At the moment, all you have is an array with one element (from your initialiser list).

    Try something like this, which is 20 elements all zero.
    Code:
        int answerKeyArray[20] = { 0 };
    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
    Oct 2012
    Posts
    14
    HAHA... omg, that worked! I actually used [100], because I think I read that somewhere in the instructor's looong instructions (that I spared you from, for the moment) and sure enough numElems stayed at 10, just like it's supposed to. Any idea how it was getting changed or where it was getting the '4' from?

    Thank you for your quick reply and help!

    P.S. You'll likely be hearing from me again with another problem in about, oh 20 mins? lol

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > numElems variable is getting changed from 10 to 4.
    Code:
    //    answerKeyArray[3] goes here
        int numElems = -1; /*number of test questions and
                        return variable from readAnswerInfo (function 1)*/
    //    answerKeyArray[2] goes here
        FILE *infile; /*declares infile as a file variable*/
    //    answerKeyArray[1] goes here
        FILE *outfile; /*declares outfile as a file variable*/
    //    answerKeyArray[0] goes here
        int answerKeyArray[] = {0};
    So if you wrote 1 2 3 4 into the first 4 'elements' of your undersized array, then the excess elements would start overwriting other variables.

    Understand that this is just a quirk of how your compiler arranged the variables in memory in this particular instance. A different compiler might arrange the variables in another order, or may even pad the ends of your array with a "dead zone", and you might never even notice (or only notice something else later on).

    Having variables change "mysteriously" is usually a sign of messing up on the sizes of arrays (or later on, allocating memory through malloc).
    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.

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    [edit]Salem has beaten me :-) [/edit]

    Quote Originally Posted by dangerous :P View Post
    Any idea how it was getting changed or where it was getting the '4' from?
    Since you have written into memory outside of your array, you have probably overwritten the value of the variable which was stored in a memory block following the array.

    Bye, Andreas
    Last edited by AndiPersti; 10-13-2012 at 03:45 AM. Reason: too slow

  6. #6
    Registered User
    Join Date
    Oct 2012
    Posts
    14
    Oooh, my instructor warned against doing this and said we would be marked down, but I didnt realize NOT declaring the size of the array could have the same result. Thanks to both of you for the explanation AND helping to save my grade from unnecessary deductions! :-)

    Don't you fret, AndiPersti, Ill have another question soon... you can get the next one ;-) lol

  7. #7
    Registered User
    Join Date
    Oct 2012
    Posts
    14

    Test Scores Program

    I think I am finally just about done with this program, believe it or not. Im just having trouble with one last piece of it. If theres anyone out there that is able to to help me, Id be most appreciative. :-)

    The first elements of the answerKeyArray and frequencyArray print as 0 and as a result, the student scores for student 1234 and student 9012 are one number too low for Q/A #1. I did have it working just fine at one point, then I changed something to fix another issue and cant remember how to get the old working code back. lol :P famous last words, right? lol

    I was going to truncate the code, but Im not sure where the problem is and what code is safe to remove or not from this post. Still using same input file I attached for the first post.

    Thanks so much in advance for your help,


    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    
    int readAnswerInfo (FILE *infilep, int numElems, int answerKeyArray[]);
    int readStudentData (FILE *infilep, int numElems, int answerKeyArray[],
                        int frequencyArray[], FILE *outfilep);
    int fillArray (FILE *infilep, int numElems, int array[]);
    int correctAnswers (int answerKeyArray[], int numElems, int studentAnswersArray[],
                        int studentID, int frequencyArray[], int score);
    void printStudentScores (int numElems, int answerKeyArray[],
                             int frequencyArray[], FILE *outfilep);
    
    int main (void)
    {
         //number of test questions and return variable
        int numElems = -1;         //from readAnswerInfo
        FILE *infile;                   //declares infile as a file variable
        FILE *outfile;                  //declares outfile as a file variable
        int answerKeyArray[100] = {0}; //declares & initializes array to 0
        int frequencyArray[100];        //declares array to 100 elements
    
        infile = fopen("test_input1.txt", "r"); //test to open input file
        if( infile == NULL )
        {
            printf("Input file didn't open\n");
            exit(100); //exit main
        } //end
    
        outfile = fopen("output.txt", "w"); //test to open output file
        if(outfile == NULL)
        {
            printf("Output file didn't open\n");
            exit(101); //exit main
        } //end
    
        //function to read in numElems
        numElems = readAnswerInfo(infile, numElems, answerKeyArray);
    
        //test for numElems
        if(numElems > 0 || numElems <= 100)
        {
            //function to process student data
            readStudentData(infile, numElems, answerKeyArray, frequencyArray, outfile);
        }
        else
            printf("Error with input file: input1.txt\n");
    
        //function to print student data and scores
        printStudentScores(numElems, answerKeyArray, frequencyArray, outfile);
    
        fclose(infile);                     //closes input file
        fclose(outfile);                    //closes output file
    
        return 0;
    } // end main
    
    
    int readAnswerInfo (FILE *infilep, int numElems, int answerKeyArray[])
    {
        //scanning numElems
        fscanf(infilep,"%d", &numElems);
    
        //function to store numElems and fill array
        fillArray(infilep, numElems, answerKeyArray);
    
        if( numElems > 0 || numElems <= 100 )
            return numElems;
        else
            return 0;
    }
    
    int readStudentData (FILE *infilep, int numElems, int answerKeyArray[], int frequencyArray[], FILE *outfilep)
    {
        int i;
        int studentID = 0;                  //student ID variable
        int studentAnswersArray[100] = {0}; //student answer array
        int score = 0;
    
         //for loop to initialize array elements to 0
        for(int i = 0; i <= 100 ; i++)
        {
          frequencyArray[i] = 0;
        }
    
        //prints headers
        printf("\nStudent ID    Score    Student Answers\n");
        for( i = 0; i < numElems; i++ )
            printf("%4d\n", studentID);  //prints studentIDs
    
        //loop to run function to fill student answer array
        //loop to run function to correct student answers
        //loop to print studentIDs and student answer arrays
        while (fscanf(infilep,"%d", &studentID) != EOF)
        {
            fillArray(infilep, numElems, studentAnswersArray);
            score = correctAnswers(answerKeyArray, numElems, studentAnswersArray, studentID, frequencyArray, score);
    
            printf("%7d\t\t%d\t", studentID, score);
    
            for( i = 0; i < numElems; i++)
            {
                printf("%4d", studentAnswersArray[i]);
            }
            printf("\n");
        }
        return 0;
    }
    
    int fillArray (FILE *infilep, int numElems, int array[])
    {
        int i;
        //for loop to fill array
        for( i = 0; i < numElems ; i++ )
            fscanf(infilep,"%d", &array[i]);
    
        return 0;
    }
    
    int correctAnswers (int answerKeyArray[], int numElems, int studentAnswersArray[],
                        int studentID, int frequencyArray[], int score)
    {
        int i;
    
        //loop to correct student scores
        for( i = 0, score = 0; i < numElems; i++)
        {
                if (answerKeyArray[i] == studentAnswersArray[i])
                {
                    score++;
                    frequencyArray[i]++;
                }
        }
        return score;
    }
    
    void printStudentScores (int numElems, int answerKeyArray[],
                             int frequencyArray[], FILE *outfilep)
    {
        int i;
        int num;
    
        printf("\nQuestion #: \t\t");
        for( num = 1; num <= numElems ; num++ )
        printf("%4d", num);
        printf("\n\n");
    
        printf("Answer Key: \t\t");
        for( i = 0; i < numElems ; i++ )
        printf("%4d", answerKeyArray[i]);
        printf("\n\n");
    
        printf("Frequency: \t\t");
        for( i = 0; i < numElems ; i++ )
        printf("%4d", frequencyArray[i]);
        printf("\n\n");
    
        return;
    }
    Attached Files Attached Files

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > for(int i = 0; i <= 100 ; i++)
    You're overrunning the ends of your arrays (again).

    Do this
    Code:
    #define MAX_SIZE 100
    Now, everywhere you have 100 in your code, you write MAX_SIZE

    And it's always going to be
    for ( i = 0 ; i < MAX_SIZE ; i++ )
    when looping over array elements.

    > int correctAnswers (int answerKeyArray[], int numElems, int studentAnswersArray[],
    > int studentID, int frequencyArray[], int score)
    You should make score a local variable. There is no point passing in junk, only to initialise it to 0 almost immediately.
    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.

  9. #9
    Registered User
    Join Date
    Oct 2012
    Posts
    14
    :P :P :P :P :P :P :P :P sorry

    i had a feeling thats what was going on.

    Okay, so i think thats how the problem with the two values changing to 0 started; i decided to define 100 and had gone thru and changed all the 100s to SIZE. I wasnt convinced it was working and when i suspected that change was the culprit of my values now being 0, i thought maybe i better change it back; guess i was better off leaving it, though.

    So, ive set the #define and changed all the 100s, and changed score to local.

    Couple of questions, please?:

    - Should i also switch out numElems for MAX_SIZE on lines 101, 114 and 126 above? Any others?
    - How do i get my two values that got changed to 0 back?
    - Im having some trouble understanding this array boundary concept (obviously). In the future, how do i make sure to stay within bounds? I had set the array size to be 100 which was much larger than I needed, but was probably also pointless after using numElems with a value of 10 when actually working with the arrays.

    Thanks for your help again, Salem!
    Last edited by dangerous :P; 10-15-2012 at 08:30 AM. Reason: added a space

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > - Should i also switch out numElems for MAX_SIZE on lines 101, 114 and 126 above? Any others?
    No, those you should leave at numElems, because at some earlier point, you determined that there were so many specific elements.

    It's maximum value should be MAX_SIZE, and this you need to enforce in readAnswerInfo and/or fillArray.

    > if( numElems > 0 || numElems <= 100 )
    This should be &&, not ||
    1234567 and -9999999 would also pass the 'or' test.

    > - How do i get my two values that got changed to 0 back?
    Don't know - I assumed it was down to array overrun.
    But if you've fixed all the loops to start at 0, and run to < (not <=), then I suggest you post your latest code.

    I only actually start running code off the board when I can't spot any more problems from just reading it.

    > - Im having some trouble understanding this array boundary concept (obviously). In the future, how do i make sure to stay within bounds?
    Well given
    type array[SIZE];
    the idiomatic loop is
    for ( i = 0 ; i < SIZE ; i++ )

    But if you're counting the elements, then it's always <= (as you almost managed in readAnswerInfo)
    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.

  11. #11
    Registered User
    Join Date
    Oct 2012
    Posts
    14
    Okay, i think i finally found it :P

    I tried to print the Student IDs twice -- once in the for loop on lines 88-89 and then again in the while loop (line 99). Somehow, i guess was rewriting the first fscanf with 8 - 0s, maybe since i had student ID = 0?, so the first 8 lines of my output file was just a 0\n0\n0\n... and THEN it printed the file correctly, the way it was supposed to. Now that i found the reason for all the 0s, I think Im good!

    I just have to say, Im sure this looks like an easy program, but it just might be the most complicated and longest one Ive ever written. Gotta say Im feelin a teensy-weensy bit proud at the moment.

    Thanks so much for your help, Salem and AndiPersti... seriously couldn't have done it without you. This forum (and your blazing fast replies) are a lifesaver!

    Im out for now... but Ill be back... guaranteed!

    L8!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Homework: calculate test scores
    By xcentirk05 in forum C++ Programming
    Replies: 15
    Last Post: 07-08-2012, 04:00 PM
  2. AVG High/Low test scores
    By BeldenML in forum C Programming
    Replies: 35
    Last Post: 10-07-2011, 04:06 PM
  3. Exam Scores Program Problems
    By ktrow_01 in forum C Programming
    Replies: 6
    Last Post: 11-24-2010, 12:32 PM
  4. test scores(avg, highest, lowest...)
    By taj777 in forum C++ Programming
    Replies: 1
    Last Post: 04-08-2010, 09:23 PM
  5. test scores
    By ucme_me in forum C Programming
    Replies: 4
    Last Post: 11-14-2001, 01:48 PM