Thread: My program unexpectedly quits

  1. #1
    Registered User
    Join Date
    Apr 2009
    Location
    CA
    Posts
    6

    My program unexpectedly quits

    Hello all,

    I am new to this forum as well as C programming so please go easy on me.

    I have looked through various faqs and other internet sites to find the answer to my current problem but so far I have been unsuccessful. I'm writing a program in C that allows you to enter student records, change test scores, and display all the records currently entered.

    So here is my problem. I am trying to store all the records in an array of structures and for the first two student entries it works fine. But for some reason when I try and add a third student the program just quits after I enter all the data and I can't figure out why. You can see in the source code there is a bold line that prints "here." After entering all the third student's data this line is printed and then the program quits so it seems the line that stores the structure in the array is causing the issue.

    I thought the problem may have been each structure using too much memory space than the array could hold so I tried increasing the size of the array to 100 but the program still quit.

    Any ideas as to why this would happen? Many thanks for any hints or clues as to how I can fix this.


    Code:
    #include<stdio.h>
    
    struct student{
           int studentID;
           char name[30];
           int prog1, prog2, prog3;
           int test1, test2, test3;
    };
    
    int addStudent(int cnt, struct student array[10]){
         struct student newStudent;
         printf("cnt = %d\n", cnt);
         printf("Enter student number: ");
         scanf("%d", &newStudent.studentID);
         printf("Enter student's name: ");
         scanf("%s", newStudent.name);
         printf("Enter program scores: ");
         scanf("%d %d %d", &newStudent.prog1, &newStudent.prog2, &newStudent.prog3);
         printf("Enter test scores: ");
         scanf("%d %d %d", &newStudent.test1, &newStudent.test2, &newStudent.test3);
         printf("here");
         array[cnt] = newStudent;
         cnt++;
         return cnt;
    }
    
    void programScores(){
         printf("Call to programScores\n");
    }
    
    void testScores(){
         printf("Call to testScores\n");
    }
    
    void deleteStudent(){
         printf("Call to deleteStudent\n");
    }
    
    void displayRecords(int cnt, struct student array[10]){
         int i;
         printf("Cnt = %d\n", cnt);
         printf("Call to displayRecords\n");
         printf("-------------------------------------------------------------------\n");
         printf("ID#   Name              Prog1   Prog2   Prog3   Test1  Test2  Test3\n");
         printf("-------------------------------------------------------------------\n");
         for(i = 0; i < cnt; i++)
         {
               printf("%-5d %-18s %-7d %-7d %-7d %-6d %-6d %-6d\n", array[i].studentID,
                      array[i].name, array[i].prog1, array[i].prog2, array[i].prog3,
                      array[i].test1, array[i].test2, array[i].test3);
         }
         
    }
    
    main()
    {
          int option = 0;
          int count = 0;
          int *ptr;
          ptr = &count;
          printf("ptr value = %d\n", *ptr);
          struct student studentArray[10];
          
          while(option != 6)
          {
               printf("1.  Add a student\n2.  Enter program scores\n");
               printf("3.  Enter Test Scores\n4.  Delete a student\n");
               printf("5.  Display all records\n6.  Quit\n");
               printf("Enter Number: ");
               scanf("%d", &option);
          
               switch(option)
               {
                    case 1: count = addStudent(count, &studentArray[10]);
                            //count++;
                            printf("Count = %d\n", count);
                            break;
                    case 2: programScores();
                            break;
                    case 3: testScores();
                            break;
                    case 4: deleteStudent();
                            break;
                    case 5: displayRecords(count, &studentArray[10]);
                            break;
                    case 6: printf("Goodbye");
                            break;
                    default: printf("Invalid Option\n");
                             break;
               }
          }
          exit(0);
    }

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Check the boundaries on your array:
    Code:
    addStudent(count, &studentArray[10]);
    Last edited by itCbitC; 04-02-2009 at 02:43 PM.

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Are you by any chance entering a first name + last name for the "name" field? When you use %s, you need to know that it will stop on the first whitespace character. If you enter "John Doe", it stops after n and before D. That means "Doe" is left in the input stream when you try your next read.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    Apr 2009
    Location
    CA
    Posts
    6
    Thanks itCbitC and quzah for the quick responses. And here is where the "going easy on me" part comes in...

    Arguments to conversion characters in scanf() are pointers.
    Are you referring to each time I use scanf or just with the string?

    Check the boundaries on your array:
    By boundaries do you mean the size of the array or is there some other meaning to boundary that I'm just not aware of? I did try resizing the array to be 100 instead of 10 and the same result occurred.

    I am currently only entering a first name to avoid the input stream problem. I originally tried using gets instead of scanf to read a first name + last name but I couldn't get it to work properly so I continued on with the scanf and just first name.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    By array boundaries, they meant check to make sure you weren't trying to input more data than your array could store. Does your program crash on the very first record you enter, or further on? Try checking the return value of scanf after each attempt at inputting data. It should help you know if you're getting what you expect. You could also try printing the contents of newStudent to ensure that what you've entered is what you are ending up with. If it's not, check your input functions.

    Another way to do this would be to first just make a small program that only tries to fill one structure. If that works, then try moving it into a function. If that works, now try it in a loop. Etc.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Never mind the scanf() part, I was wrong about it as I didn't realize that name is an array. Change your addStudent() to:
    Code:
    addStudent(count, studentArray+count);

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    No. Just pass it studentArray and index it as an array using count. The only way adding count to it works is if you pass it as a pointer to an element, and not the entire array (which is really just a pointer to its first element):
    Code:
    void addStudent( int, struct student * );
    ...
    struct student array[ X ];
    ...
    addStudent( 5, array + 5 );
    Otherwise you're going to break something.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Apr 2009
    Location
    CA
    Posts
    6
    My input is working fine seeing as how one of the options of the program is to display all the records that have been entered and when I choose that option all info for the first two students is displayed properly(and when I originally wrote the addStudent function I was displaying the data entered directly after entering it to double check). But for some reason when I try and add a third student the program quits when at the line that puts newStudent into the array.

    I am now wondering however if my problem is related to the code I have written or something else. I have been testing my program via a command prompt in XP and the same result occurs every time, quits when adding the third student. I just ftp'd my program to the Unix machine I do my demos on, compiled it, and it runs without any problems. I can enter as many students as I like and each one is displayed properly.

    Is there a limitation to using a command prompt when testing or running compiled programs written in C?

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It works fine in cygwin, once I included the missing header, and made it stop throwing warning messages. You should start compiling with warning messages turned on, and listen to them.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Can you post your updated code.

  11. #11
    Registered User
    Join Date
    Apr 2009
    Location
    CA
    Posts
    6
    Here is the "updated" code. I say "updated" because I haven't made any changes to how the functions use parameters or how they are passed, just a few minor details here and there. (printing variables to see if they are updating correctly, etc...)

    I'm still having an issue but the issue is different when I use a command prompt in XP and when I run the program on a Unix machine. With the XP command prompt, when I choose the optoin to display the student records on the screen they display with no problem (as long as there are only two records total). When I try and add a third the program quits after I enter all the student data.

    When running the program on a Unix machine I can enter as many students as I like and the program never quits, but when I display the student records everything is displayed fine with the exception of the first student's name. For some reason it is limited to only four characters.

    Code:
    #include<stdio.h>
    
    struct student{
           int studentID;
           char name[30];
           int prog1, prog2, prog3;
           int test1, test2, test3;
    };
    
    int addStudent(int cnt, struct student array[20]){
         struct student newStudent;
         if(cnt < 20)
         {
            printf("Enter student number: ");
            scanf("%d", &newStudent.studentID);
            printf("Enter student's name: ");
            scanf("%s", newStudent.name);
            printf("%s\n", newStudent.name);
            printf("Enter program scores: ");
            scanf("%d %d %d", &newStudent.prog1, &newStudent.prog2, &newStudent.prog3);
            printf("Enter test scores: ");
            scanf("%d %d %d", &newStudent.test1, &newStudent.test2, &newStudent.test3);
            array[cnt] = newStudent;
            cnt++;
         }
            return cnt;
    }
    
    void programScores(){
         printf("Call to programScores\n");
    }
    
    void testScores(){
         printf("Call to testScores\n");
    }
    
    void deleteStudent(){
         printf("Call to deleteStudent\n");
    }
    
    void displayRecords(int cnt, struct student array[20]){
         int i;
         printf("-------------------------------------------------------------------\n");
         printf("ID#   Name              Prog1   Prog2   Prog3   Test1  Test2  Test3\n");
         printf("-------------------------------------------------------------------\n");
         for(i = 0; i < cnt; i++)
         {
               printf("%-5d %-18s %-7d %-7d %-7d %-6d %-6d %-6d\n", array[i].studentID,
                      array[i].name, array[i].prog1, array[i].prog2, array[i].prog3,
                      array[i].test1, array[i].test2, array[i].test3);
         }
         
    }
    
    main()
    {
          int option = 0;
          int count = 0;
          struct student studentArray[20];
          
          while(option != 6)
          {
               printf("1.  Add a student\n2.  Enter program scores\n");
               printf("3.  Enter Test Scores\n4.  Delete a student\n");
               printf("5.  Display all records\n6.  Quit\n");
               printf("Enter Number: ");
               scanf("%d", &option);
          
               switch(option)
               {
                    case 1: count = addStudent(count, &studentArray[20]);
                            break;
                    case 2: programScores();
                            break;
                    case 3: testScores();
                            break;
                    case 4: deleteStudent();
                            break;
                    case 5: displayRecords(count, &studentArray[20]);
                            break;
                    case 6: printf("Goodbye\n");
                            break;
                    default: printf("Invalid Option\n");
                             break;
               }
          }
          exit(0);
    }

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    &studentArray[20] is not a pointer to array, is pointer just after the last member of the array
    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

  13. #13
    Registered User
    Join Date
    Apr 2009
    Location
    CA
    Posts
    6
    It works fine in cygwin, once I included the missing header, and made it stop throwing warning messages. You should start compiling with warning messages turned on, and listen to them.
    I'm currently using DEV C++ to write my code. Is there a way to turn the warning messages on that you're referring to? And what is the header file that I'm missing?

    &studentArray[20] is not a pointer to array, is pointer just after the last member of the array
    I was confusing myself about passing arrays as parameters. I was thinking of passing 2D arrays in which case the size of the second dimension ( array[][5]) needs to passed. At least that's how I understand it. Anyways, I made the change but I still have the same problem.

    For some reason that I'm still unable to determine it seems that the name of the first student I enter is some how being corrupted or not stored in the array correctly and is causing my problem. I believe my input is working correctly since after I enter the name "JoeBlow" I echo it directly afterwards from the corresponding struct and I see on the screen "JoeBlow." But when I choose the option to display all student records I see the name displayed as "JoeB." And yes, the is supposed to be there. Some how some garbage or whatever the ASCII value is for the is being written over part of the name. Any number of students added afterwards look just fine.

  14. #14
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Here's my 2c.
    Code:
    #include<stdio.h>
    
    struct student{
           int studentID;
           char name[30];
           int prog1, prog2, prog3;
           int test1, test2, test3;
    };
    int addStudent(int cnt, struct student *newStudent)
    {
         if(cnt < 20)
         {
            printf("Enter student number: ");
            scanf("%d", &(*newStudent).studentID);
            printf("Enter student's name: ");
            scanf("%s", (*newStudent).name);
            printf("Enter program scores: ");
            scanf("%d %d %d", &(*newStudent).prog1, &(*newStudent).prog2, &(*newStudent).prog3);
            printf("Enter test scores: ");
            scanf("%d %d %d", &(*newStudent).test1, &(*newStudent).test2, &(*newStudent).test3);
            cnt++;
         }
            return cnt;
    }
    void programScores(){
         printf("Call to programScores\n");
    }
    void testScores(){
         printf("Call to testScores\n");
    }
    void deleteStudent(){
         printf("Call to deleteStudent\n");
    }
    void displayRecords(int cnt, struct student array[]){
         int i;
         printf("-------------------------------------------------------------------\n");
         printf("ID#   Name              Prog1   Prog2   Prog3   Test1  Test2  Test3\n");
         printf("-------------------------------------------------------------------\n");
         for(i = 0; i < cnt; i++)
         {
               printf("%-5d %-18s %-7d %-7d %-7d %-6d %-6d %-6d\n", array[i].studentID,
                      array[i].name, array[i].prog1, array[i].prog2, array[i].prog3,
                      array[i].test1, array[i].test2, array[i].test3);
         }
    
    }
    int main(void)
    {
          int option = 0;
          int count = 0;
          struct student studentArray[20];
    
          while(option != 6)
          {
               printf("1.  Add a student\n2.  Enter program scores\n");
               printf("3.  Enter Test Scores\n4.  Delete a student\n");
               printf("5.  Display all records\n6.  Quit\n");
               printf("Enter Number: ");
               scanf("%d", &option);
    
               switch(option)
               {
                    case 1: count = addStudent(count, studentArray+count);
                            break;
                    case 2: programScores();
                            break;
                    case 3: testScores();
                            break;
                    case 4: deleteStudent();
                            break;
                    case 5: displayRecords(count, studentArray);
                            break;
                    case 6: printf("Goodbye\n");
                            break;
                    default: printf("Invalid Option\n");
                             break;
               }
          }
          return 0;
    }
    Last edited by itCbitC; 04-05-2009 at 10:35 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Program ends unexpectedly
    By keelhauled in forum C Programming
    Replies: 3
    Last Post: 10-12-2007, 05:41 PM
  2. Using variables in system()
    By Afro in forum C Programming
    Replies: 8
    Last Post: 07-03-2007, 12:27 PM
  3. BOOKKEEPING PROGRAM, need help!
    By yabud in forum C Programming
    Replies: 3
    Last Post: 11-16-2006, 11:17 PM
  4. I need some help with my program please.
    By agentxx04 in forum C Programming
    Replies: 9
    Last Post: 09-26-2004, 07:51 AM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM