Thread: Program will not restart properly

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    14

    Program will not restart properly

    Hi,

    I am almost at the stage of completing a program for an assignment, however I cannot seem to get the user to restart the program properly...

    I am using the code below...

    Code:
    do {
    
    printf("\n  Create Size of Matrix A [MAX 4 X 4 Matrix]:\n");
            
            do {
                   
            printf("\n             Number of Rows [R] = ");
            
            gets(vld);
            chk = sscanf(vld, "%d",&RowA);
            
            if (chk != 1)
                   { printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
                   else
                   if (RowA < 0 || RowA > 4)
                   { printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                   
                }   while (RowA < 0 || RowA > 4);
                
            do {                
            printf("\n          Number of Columns [C] = ");
            
            gets(vld);
            chk = sscanf(vld, "%d",&ColA);
            
            if (chk != 1)
                   { printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
                   else
                   if (ColA < 0 || ColA > 4)
                   { printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                
                }   while (ColA < 0 || ColA > 4);
    
    [rest of program]
    
    printf("\nWould you like to restart the program? (y = Yes, n = No): \n");
        getchar();
        c = getchar();
        
      } while ((c == 'y' || c == 'Y'));
    
        return (0);
        }
    When the user hits 'y', the console just closes and will not restart? Any ideas what's wrong??

    Help would be very much appreciated!

    Thanks!

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    Your indentation is horrible. It's really easy to screw up your logic, and really hard to find and fix problems, if you can't easily see what your program is doing. Read this: SourceForge.net: Indentation - cpwiki. Pick a good, clear indentation style, and follow it religiously.

    You call getchar twice, and only the second one is used to continue the program. Maybe this is the problem, but it's hard to tell what all you do with your input buffer, seeing as how you didn't provide all your code. Maybe you already did something to get rid of leftover newlines, so that first getchar eats up the 'y'. You could also try printing it out c right after you read it (perhaps along with it's numeric value) to see what it's value is before the end of your program. Something like printf("c = %c (%d)\n", c, c);.

    EDIT: And for the love of all things good and holy, DON'T USE gets!!!! Read this: http://faq.cprogramming.com/cgi-bin/...&id=1043284351. Then replace all your usages of gets with fgets. Just remember, fgets leaves the newline in there, so you need to strip it. There's an example here: http://faq.cprogramming.com/cgi-bin/...&id=1043284385. It's generally bad to mix input styles (fgets, getchar and scanf). I like using fgets to get a line, and sscanf to parse data out as needed.
    Last edited by anduril462; 04-19-2012 at 12:12 PM.

  3. #3
    Registered User
    Join Date
    Nov 2011
    Posts
    14
    Thanks for your reply! I shall look at the fgets code and change everything accordingly. I removed the getchar(); line and it seems to restart the program back to the beginning, however it is skipping out the request for matrix A's rows...

    Here is the code:

    Code:
    #include <stdio.h>
    #include <math.h>
    
    
    /* Function Prototype: Enter Matrix Data */
    int Matrix_Data(int a[4][4],int x,int y)
    {
        int i,j;
        char vld[80], c;
        char ch;
        int chk;
       
        for(i=0;i<x;i++)
        for(j=0;j<y;j++)
        
        do {
            printf ("       Enter data integer, PRESS ENTER: ");
            
            gets(vld);
            chk = sscanf(vld, "%d",&a[i][j]);
            
            if (chk != 1)
               {    printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
            else
            if (a[i][j] < 0 || a[i][j] > 99)
               {    printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                   
            }   while (a[i][j] < 0 || a[i][j] > 99);
            
        return (0);
    }
    
    
    /* Function Prototype: Display Matrix Data */
    int Display_Matrix(int a[4][4],int x,int y)
    {
        int i,j;
        
        for(i=0;i<x;i++)
        {
            for(j=0;j<y;j++)
           
            printf("%16d",a[i][j]);
            printf("\n\n");
        }
        
        return (0);
    }
    
    
    int main(void)
    
    
    {
        int i,j, RowA, ColA, RowB, ColB, k;
        int MXA[4][4], MXB[4][4], MLT[4][4];
        
        char vld[80], c;
        int chk;
        
        /* Introduction */
            
        printf("                             Matrix Multiplier\n");
        printf("                             _________________\n");
        printf("\n    Welcome to the Matrix Multiplier.  This program is designed to output \n             the result of multiplying two, 4 X 4 matrices.\n");
        printf("\n_______________________________________________________________________________\n");
        
        /* End Introduction */
        
        do {
        
        /*Matrix A*/        
            
            printf("\n  Create Size of Matrix A [MAX 4 X 4 Matrix]:\n");
            
            do {
                
                printf("\n             Number of Rows [R] = ");
            
                gets(vld);
                chk = sscanf(vld, "%d",&RowA);
            
                if (chk != 1)
                   {    printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
                else
                if (RowA < 0 || RowA > 4)
                   {    printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                   
                }   while (RowA < 0 || RowA > 4);
                
            do {                
                
                printf("\n          Number of Columns [C] = ");
            
                gets(vld);
                chk = sscanf(vld, "%d",&ColA);
            
                if (chk != 1)
                   {    printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
                else
                if (ColA < 0 || ColA > 4)
                   {    printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                
                }   while (ColA < 0 || ColA > 4);
                
        /* End Matrix A */
        /* Matrix B */
                
            printf("\n  Create Size of Matrix B [MAX 4 X 4 Matrix]:\n");
            
            do {
                       
                printf("\n             Number of Rows [R] = ");
            
                gets(vld);
                chk = sscanf(vld, "%d",&RowB);
            
                if (chk != 1)
                   {    printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
                else
                if (RowB < 0 || RowB > 4)
                   {    printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                
                }   while (RowB < 0 || RowB > 4);
            
            do {                
            
                printf("\n          Number of Columns [C] = ");
            
                gets(vld);
                chk = sscanf(vld, "%d",&ColB);
            
                if (chk != 1)
                   {    printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
                else
                if (ColB < 0 || ColB > 4)
                   {    printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                
                }   while (ColB < 0 || ColB > 4);
                
        /* End Matrix B */
            
            printf("\n_______________________________________________________________________________\n");
        
        /* Enter Data for both Matrices */
            
            if (RowB == ColA)
               {
                    
                printf("\n  DATA for Matrix A\n\n");
                Matrix_Data(MXA, RowA, ColA); //Call Matrix_Data Prototype for Matrix A
                
                printf("\n  The structure of Matrix A is as follows: \n\n");
                       
                       for (i=0;i<RowA;i++)
                       {
                           for(j=0;j<ColA;j++)
                           printf("          %d\t",MXA[i][j]);
                           printf("\n\n");
                       }
                
                printf("\n  DATA for Matrix B\n\n");
                Matrix_Data(MXB, RowB, ColB); //Call Matrix_Data Prototype for Matrix B
                
                printf("\n  The structure of Matrix B is as follows: \n\n");
                       
                       for (i=0;i<RowB;i++)
                       {
                           for(j=0;j<ColB;j++)
                           printf("          %d\t",MXB[i][j]);
                           printf("\n\n");
                       }
        /* End Enter Data for both Matrices */
                
                printf("\n_______________________________________________________________________________\n");
                
        /* Multiplication of Matrix A and Matrix B */
                
                for(i=0;i<RowA;++i)
                for(j=0;j<ColB;++j)
                   {
                       MLT[i][j]=0;
                       for(k=0;k<ColA;++k)
                       MLT[i][j] += MXA[i][k]*MXB[k][j];
                   }
                
                printf("\n  The result of multiplying Matrix A and Matrix B is as follows: \n\n");
                Display_Matrix(MLT, RowA, ColB); //Call Display_Matrix Prototype
            }
            else
                {
                     printf("\n  The Size of Matrices you have chosen cannot be multiplied.\n  Please check again.\n\n");
                }
                
                printf("\n_______________________________________________________________________________\n");
        /* End Program */
        
        printf("\nWould you like to restart the program? (y = Yes, n = No): \n");
        c = getchar();
    
    
                printf("\n_______________________________________________________________________________\n");
        
        } while ((c == 'y' || c == 'Y'));                    
             
        //system ("PAUSE");
        return (0);
        
    }
    Why is it skipping out the request for matrix A's rows when I hit yes to restarting the program?

    Thank you!

  4. #4
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    Code:
        printf("\nWould you like to restart the program? (y = Yes, n = No): \n");
        c = getchar();
    That leaves the carriage return in the stream. so next time you call gets, it only read the carraige return. thus it fails.
    Code:
        printf("\nWould you like to restart the program? (y = Yes, n = No): \n");
        c = getchar();
       getchar();
    insert the getchar() after assign to "c" will get rid of that carriage return you enter. There may be other way to fix this, but i don't remember. Good luck with your course.

    EDIT: btw, use a loops to replace this:
    Code:
    printf("\n_______________________________________________________________________________\n");
    , they are so annoying and distracting to read your code.

    Edit2: those error checking keeps coming up, write a separate function for them.
    Last edited by nimitzhunter; 04-21-2012 at 01:35 PM.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  5. #5
    Registered User
    Join Date
    Nov 2011
    Posts
    14
    Thank you! That worked!

    What kind of loop should I use to replace the lines? And I've tried to put the error checking code into a function but I can't find a way to make it work at all, gave up and left it as is.

  6. #6
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    Code:
    void drawline()
    {
      printf("\n");
      for (int i = 0 ; i < 10 ; ++i)
        printf("_"):
      printf("\n");
    }
    something like that.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  7. #7
    Registered User
    Join Date
    Nov 2011
    Posts
    14
    Thanks again!

    I've tried to put the error checking into a function prototype which works...kind of..

    Here's the code in the function I have called Check..

    Code:
    int Check(int a){
        char vld[80];
        int chk;
    
    
        do {
            printf("\n\t\t                = ");
            gets(vld);
            chk = sscanf(vld, "%d",&a);
        
        if (chk != 1)
           {    printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
        else
        if (a < 0 || a > 4)
           {    printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                   
           }   while (a < 0 || a > 4);
    
    
    }
    I have called this code here in main....

    Code:
    printf("\n  CREATE SIZE of Matrix A [MAX 4 X 4 Matrix]:\n");                          
            printf("\n             Number of Rows [R]");
            printf("\n             ..................");
            Check(RowA);
            printf("\n %d",RowA);            
            
            printf("\n          Number of Columns [C]");
            printf("\n          .....................");
            Check(ColA);
            printf("\n %d",ColA);
    However, it is not storing the user number entered into the variable RowA (or ColA), as you can see by the printf's I've inserted to check what is actually going into them.

    Why is it not storing the number as expected? For example, if I enter 3, what actually goes into RowA is a random number e.g. 7682520

    Thank you!

  8. #8
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    you were right on track with your function; just need to make a few changes.
    Code:
    int Check(){                                                                // don't need to pass in anything because we will return the read in value to CollA in main
        char vld[80];
        int chk;
        int a;    // "a" need to be declared somewhere. 
     
        do {
            printf("\n\t\t                = ");
            gets(vld);
            chk = sscanf(vld, "%d",&a);
         
        if (chk != 1)
           {    printf ("\n             ERROR; You have entered a character.  Please Enter a number!\n"); }
        else
        if (a < 0 || a > 4)
           {    printf ("\n             You have entered a number out of range.\n             Please re-enter!\n"); }
                    
           }   while (a < 0 || a > 4);
       return a; // You have to return this value , otherwise it will disappear
    }
    Then in your main
    Code:
     printf("\n  CREATE SIZE of Matrix A [MAX 4 X 4 Matrix]:\n");                          
            printf("\n             Number of Rows [R]");
            printf("\n             ..................");
            RowA=Check();
            printf("\n %d",RowA);            
             
            printf("\n          Number of Columns [C]");
            printf("\n          .....................");
            ColA=Check();
            printf("\n %d",ColA);
    Remember that when you declare
    Code:
    some_type function(some_type variable_A)
    the function will make a copy of variable_A and work on the copy. Whatever operation on that variable_A will disappear if you don't return the result. Another way to go about this is to pass in a pointer
    Code:
    some_type function(some_type * variable_A)
    .
    The addressed is assigned somewhere else, so it wouldn't go out of scope when the function call finishes.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  9. #9
    Registered User
    Join Date
    Nov 2011
    Posts
    14
    Thank you so much, that's cleared up my problem, and has taught me a few things! Really appreciate the help!!

    EDIT: Just run into a little issue....when the program asks for an integer for RowA for example, and I type in a letter, it is skipping out the character checking in the check function and continuing the program to requesting ColA...

    Any ideas why its not requesting I re-enter a value for RowA..im guessing the loop is placed in the wrong order but I cannot establish what the right one would be?
    Last edited by nelly26; 04-22-2012 at 02:19 PM.

  10. #10
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    When sscanf fails, "a" is undefined, so it could take on any value. So when you do the conditional check in while, sometimes it fails, sometimes it passes ( this bug exists in your original code, but you didn't observe it because RowA takes on a huge value so it passes the conditional check, so your code loops back to ask for the dimension again. ).


    Code:
    int Check(){                                                               
    	char vld[80];
    	int chk;
    	int a;    
    	do			{
    		// don't need this line , it make the print out looks ugly printf("\n\t\t                = ");
    		gets(vld);
    		chk = sscanf(vld, "%d",&a);
         
    		if (chk != 1)
    			{
                                    a=-1; // make sure that "a" will satisfy the condtion (a<0 || a>4) to loop back again. 
    				printf ("\n    ~%d~         ERROR; You have entered a character. Rentervalue=",a);
    			}
    		else if (a < 0 || a > 4)
    			{
    				printf ("\n             You have entered a number out of range.\n             Please re-enter!\n");
    			}
                    
    	}   while (a < 0 || a > 4);
    	return a;
    }
    for formating and leaner looks, do this instead
    Code:
            printf("\n  Create Size of Matrix A [MAX 4 X 4 Matrix]:\n");
    				printf("\n             Number of Rows [R] = ");
            RowA=Check();
            //printf("\n %d",RowA);  
            printf("\n          Number of Columns [C] = ");
            ColA=Check()
            //printf("\n %d",ColA);
    Last edited by nimitzhunter; 04-22-2012 at 03:03 PM.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  11. #11
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    , if I enter 3, what actually goes into RowA is a random number e.g. 7682520
    Btw, you have already observed this undefined behavior of uninitialized variable. RowA with the such large random value is what passes your conditionals in the original code; and this feature is a bug, don't count on it.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  12. #12
    Registered User
    Join Date
    Nov 2011
    Posts
    14
    Ahh ok...with the a=-1 in the code it works as I expect it to....right now I'm just going through the code and making sure I understand it. I don't quite understand how the a=-1 relates to the letter input check in the loop, and why it works?

    The reason for that ugly printf (and I know it's ugly ) is because if the user enters a wrong input, i.e. and letter or number out of range, I'd like the re-entry request to be in line with the old entry so that it looks neater upon display. Without that printf it just goes to a newline and off centres the display, making it look a bit untidy...the code looks better without it but I'm unsure as to how I can make it look better with a different form of code, that looks better...

    Btw apologies for all these questions, really want to finish with a good piece of coding which I can understand well

  13. #13
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    When we declare "int a",we haven't initialized/assigned it to any value; so 'a' take on whatever value at the memory location it's created . In that case, 'a' could be 0, it could be 34235357230582930850293 or some other random number. If you're lucky, "a" take on a large value, and it satisfies "a>4" condition in the loop to go back and ask for the valid entry (which happened in your original code). If you are unlucky, 'a' would take on some value between 0 and 4; and your loop exits (which happens in function Check()). By forcing "a" to be "-1", you're satisfying "a<0" condition to loop back and retry. So be very careful with uninitialized variables in C; it will cause you lots of headache.
    "All that we see or seem
    Is but a dream within a dream." - Poe

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to restart a program using loop?
    By NewbieCProgramm in forum C Programming
    Replies: 4
    Last Post: 12-05-2011, 10:41 AM
  2. Code to restart/reload program
    By GanonsSpirit in forum C++ Programming
    Replies: 7
    Last Post: 09-20-2007, 12:34 AM
  3. restart the program
    By kellymart87 in forum C++ Programming
    Replies: 15
    Last Post: 04-17-2007, 10:04 PM
  4. restart program
    By kellymart87 in forum C++ Programming
    Replies: 2
    Last Post: 04-16-2007, 11:18 PM
  5. How to restart a program without closing it...
    By D4050 in forum C++ Programming
    Replies: 16
    Last Post: 10-31-2001, 12:38 PM