3

Scanf Infinite loop

view full story
linux-howto

http://www.daniweb.com – Hey DaniWeb. I am getting stuck in an infinite loop when I input a character instead of an integer during a scanf("%d"....); I know this is because C doesn't provide any built in error checking. I know I can fix this by using getchar() in place of scanf, and changing my variable to a character, then converting it to an int, but it would make my life alot simpler if there were another way around this. Can anyone give me some help please? Code: #include<stdio.h> #include<stdlib.h> #include <math.h> struct T_vector {       float *data;       int size; } vector1, vector2; struct T_Matrix{       struct T_vector row[3]; } matrix1, matrix2; //------------------------------------------------------------------------------ // print matrix 1 function below //              -> prints off the contents of matrix 1 void print_matrix1(){     int i=0,j=0;     for(j=0;j<3;j++){           printf("[");           for(i=0;i<3;i++){               printf("%6.2f ",matrix1.row[j].data[i]);           }           printf("]\n");     } } //------------------------------------------------------------------------------ // print matrix 2 function below //              -> prints off the contents of matrix 2 void print_matrix2(){     int i=0,j=0;     for(j=0;j<3;j++){           printf("[");           for(i=0;i<3;i++){               printf("%6.2f ",matrix2.row[j].data[i]);           }           printf("]\n");     } } //------------------------------------------------------------------------------ // print menu function below //            -> simply prints the options void printmenu(){         printf("\n\         (1)Enter vector 1.\n\         (2)Enter vector 2.\n\         (3)Enter 3x3 matrix 1.\n\         (4)Enter 3x3 matrix 2.\n\         (5)Find magnitude of vector.\n\         (6)Normalize the vector.\n\         (7)Find dot product of vector 1 and 2.\n\         (8)Find the inverse matrix.\n\         (9)Transpose a matrix.\n\         (10)Find product of matrix 1 and 2.\n\         (11)Quit\n\n"); } //------------------------------------------------------------------------------ // magnitude function below //          ->accepts a pointer to a vector and it's size float magnitude(float *vector, int size){       int i;       float mag = 0, square=0;       for(i=0;i<size;i++){           square += vector[i]*vector[i];           }       mag = sqrt(square);       return mag; } //------------------------------------------------------------------------------ //normalize function below //          -> accepts a pointer to a vector and it's size int normalize(float *vector, int size){     int i;     float mag = magnitude(vector, size);     if(mag==0) return 1;     for(i=0;i<size;i++)vector[i]=vector[i]/mag;     return 0;     } //------------------------------------------------------------------------------ // transpose function below void transpose(struct T_Matrix *matrix){     int i, j, temp_matrix[3][3];     printf("Tran");     for(i=0;i<3;i++){           printf("[");           for(j=0;j<3;j++)printf("%6.2f ",(*matrix).row[i].data[j]);           if(i==0)printf("] = [");           else  printf("]  [");           for(j=0;j<3;j++)printf("%6.2f ",(*matrix).row[j].data[i]);           printf("]\n    ");     }           for(i=0;i<3;i++){               for(j=0;j<3;j++)temp_matrix[j][i]=(*matrix).row[i].data[j];                    }           for(i=0;i<3;i++){               for(j=0;j<3;j++)(*matrix).row[i].data[j]=temp_matrix[i][j];                        } } //------------------------------------------------------------------------------ // dot product function below float dot_product(float *vector1, float *vector2, int size){       int i;       float dot=0;       printf("\n\n");       for(i=0;i<size;i++){           dot = dot+vector1[i]*vector2[i];                    } return dot; } //------------------------------------------------------------------------------ // multiply function below void multiply(struct T_Matrix *matrix3, struct T_Matrix *matrix4){     int i, j, k;     float temp_matrix[3][3]={{0,0,0},{0,0,0},{0,0,0}};     for(i=0;i<3;i++){         for(j=0;j<3;j++){             for(k=0;k<3;k++){                 temp_matrix[i][j]=temp_matrix[i][j]\                 +(*matrix3).row[i].data[k]*(*matrix4).row[k].data[j];             }         }     }     for(i=0;i<3;i++){           printf("[");           for(j=0;j<3;j++)printf("%6.2f ",(*matrix3).row[i].data[j]);           if(i==1)printf("] x [");           else printf("]  [");           for(j=0;j<3;j++)printf("%6.2f ",(*matrix4).row[i].data[j]);           if(i==1)printf("] = [");           else printf("]  [");           for(j=0;j<3;j++)printf("%6.2f ",temp_matrix[i][j]);           printf("]\n");     }      for(i=0;i<3;i++){         for(j=0;j<3;j++){                 (*matrix3).row[i].data[j]=temp_matrix[i][j];         }     }     } //------------------------------------------------------------------------------ // inverse function below int inverse(struct T_Matrix *matrix){     int i=0, j=0, k=0; // loop controls     float det=0, mat[3][3]={0,0,0,0,0,0,0,0,0}; // temp store the matrix     float inv[3][3]={0,0,0,0,0,0,0,0,0}; // temp. store the inverse matrix     for(i=0;i<3;i++){           for(j=0;j<3;j++){               mat[i][j] = (*matrix).row[i].data[j];           }     } // This is where I calculate the determinate of a 3x3 matrix     det += mat[0][0]*(mat[1][1]*mat[2][2]-mat[1][2]*mat[2][1]) \     - mat[0][1]*(mat[1][0]*mat[2][2]-mat[1][2]*mat[2][0]) \     + mat[0][2]*(mat[1][0]*mat[2][1]-mat[1][1]*mat[2][0]);     if(det==0){ // error checking for determinate               printf("Error. Matrix has no inverse.");               return 1;     } // This is where I calculate the inverse     inv[0][0]=(mat[1][1]*mat[2][2]-mat[1][2]*mat[2][1])/det;     inv[0][1]=(mat[0][2]*mat[2][1]-mat[0][1]*mat[2][2])/det;     inv[0][2]=(mat[0][1]*mat[1][2]-mat[0][2]*mat[1][1])/det;     inv[1][0]=(mat[1][2]*mat[2][0]-mat[1][0]*mat[2][2])/det;     inv[1][1]=(mat[0][0]*mat[2][2]-mat[0][2]*mat[2][0])/det;     inv[1][2]=(mat[0][2]*mat[1][0]-mat[0][0]*mat[1][2])/det;     inv[2][0]=(mat[1][0]*mat[2][1]-mat[1][1]*mat[2][0])/det;     inv[2][1]=(mat[0][1]*mat[2][0]-mat[0][0]*mat[2][1])/det;     inv[2][2]=(mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0])/det; // Here, I copy it back to the passed in matrix     for(i=0;i<3;i++){         for(j=0;j<3;j++)(*matrix).row[i].data[j]=inv[i][j];     } // Printing off the desired output     printf("\nInv");     for(i=0;i<3;i++){         printf("[");         for(j=0;j<3;j++)printf("%6.2f ",mat[i][j]);         if(i==0)printf("] = [");         else printf("]  [");         for(j=0;j<3;j++)printf("%6.2f ",(*matrix).row[i].data[j]);         printf("]\n  ");     }     return 0;         }         //------------------------------------------------------------------------------ // main below int main(){     int i, j, command;     float dotproduct; // loop controls, command var.s and dotprod.     float mag_vector1, mag_vector2; // var.s for the magnitudes start: // I use this to restart the program     i=0, j=0, command=dotproduct=0; // I reset the variables each iteration     mag_vector1=mag_vector2=0;     printmenu(); // to print / reprint the menu     printf("\n\n");     printf("Please enter the number of the command: ");     scanf("%d",&command); fflush(stdin);         switch(command){     case 1:         printf("\nNote: Non-numerical characters will be accepted as 0.");         printf("\nHow long is vector 1?");         scanf("%d",&vector1.size);         vector1.data = calloc(vector1.size, sizeof(float));         for(i=0;i<vector1.size;i++){             printf("Enter the value in position %d: ",i);             scanf("%f",&vector1.data[i]); fflush(stdin);         }         printf("\n\n");       break;     case 2:         printf("Note: Non-numerical characters will be accepted as 0.");         printf("\nHow long is vector 2?");         scanf("%d",&vector2.size);         vector2.data = calloc(vector2.size, sizeof(float));         for(i=0;i<vector2.size;i++){             printf("Enter the value in position %d: ",i);             scanf("%f",&vector2.data[i]); fflush(stdin);         }         printf("\n\n");         break;            case 3:         printf("Note: Non-numerical characters will be accepted as 0.");         matrix1.row[0].data = calloc(3,sizeof(float));         for(i=0;i<3;i++){                 printf("\nEnter # at row 1 column %d: ",i+1);                 scanf("%f",&matrix1.row[0].data[i]); fflush(stdin);         }         matrix1.row[1].data = calloc(3,sizeof(float));         for(i=0;i<3;i++){                 printf("\nEnter # at row 2 column %d: ",i+1);                 scanf("%f",&matrix1.row[1].data[i]); fflush(stdin);         }         matrix1.row[2].data = calloc(3,sizeof(float));         for(i=0;i<3;i++){                 printf("\nEnter # at row 3 column %d: ",i+1);                 scanf("%f",&matrix1.row[2].data[i]); fflush(stdin);         }         print_matrix1();                 printf("\n\n");         break;     case 4:         printf("\nNote: Non-numerical characters will be accepted as 0.");         matrix2.row[0].data = calloc(3,sizeof(float));         for(i=0;i<3;i++){                 printf("\nEnter # at row 1 column %d: ",i+1);                 scanf("%f",&matrix2.row[0].data[i]); fflush(stdin);         }         matrix2.row[1].data = calloc(3,sizeof(float));         for(i=0;i<3;i++){                 printf("\nEnter # at row 2 column %d: ",i+1);                 scanf("%f",&matrix2.row[1].data[i]); fflush(stdin);         }         matrix2.row[2].data = calloc(3,sizeof(float));         for(i=0;i<3;i++){                 printf("\nEnter # at row 3 column %d: ",i+1);                 scanf("%f",&matrix2.row[2].data[i]); fflush(stdin);         }         print_matrix2();         printf("\n\n");         break;     case 5:         i=0; // set i so it can be used as command choice         printf("Find magnitude for vector 1 or 2: ");         scanf("%d",&i);  // choose input         if(i==1){                 //calculate magnitude                 mag_vector1 = magnitude(vector1.data, vector1.size);                 //print off correct output                 printf("\n\n|[");                 for(i=0;i<vector1.size;i++)printf("%.2f ",vector1.data[i]);                 printf("]| = %.2f\n",mag_vector1);         }         else if(i==2){             //calculate magnitude             mag_vector2 = magnitude(vector2.data, vector2.size);             // print off correct output             printf("\n\n|[");             for(i=0;i<vector1.size;i++)printf("%.2f ",vector1.data[i]);             printf("]| = %f\n",mag_vector2);             }         else {             printf("\nError. Not a valid input.\n");             break; // check for correct input         }         printf("\n\n");         break;     case 6:         printf("Normalize vector 1 or 2: "); // Ask which one?         scanf("%d", &i);         if(i==1){                 // print off beginning                 printf("\n\nnorm[");                 for(i=0;i<vector1.size;i++)printf("%.2f ",vector1.data[i]);                 printf("] = [");                 // do calculations                 normalize(vector1.data, vector1.size);                 // print second half                 for(i=0;i<vector1.size;i++)printf("%.2f ",vector1.data[i]);                 printf("]\n\n");         }         else if(i==2){                 // print off beginning                 printf("\n\nnorm[");                 for(i=0;i<vector2.size;i++)printf("%.2f ",vector2.data[i]);                 printf("] = [");                 // do calculations                 normalize(vector2.data, vector2.size);                 // print second half                 for(i=0;i<vector2.size;i++)printf("%.2f ",vector2.data[i]);                 printf("]\n\n");         }         else printf("\nError. Improper input.\n\n");         printf("\n\n");         break;     case 7:         if(vector1.size!=vector2.size){ // must be equal size for dot product             printf("Error. Vectors not of equal size.");             break;             }         dotproduct = dot_product(vector1.data,vector2.data,vector1.size);         // print off the correct formatted output         printf("\n[");         for(i=0;i<vector1.size;i++) printf("%.2f ",vector1.data[i]);         printf("]dot[");         for(i=0;i<vector2.size;i++) printf("%.2f ",vector2.data[i]);         printf("] = %f",dotproduct);                 printf("\n\n");         break;     case 8:         // run inverse function         inverse(&matrix1);         printf("\n\n");         break;     case 9:         i=0; // clear i so it can be used as command variable         printf("Transpose matrix 1 or 2? ");         scanf("%d",&i);         if(i==1){                 printf("\n\n");                 transpose(&matrix1); // pass in matrix1 to inverse function                 printf("\n\n");              }         else if(i==2){                 printf("\n\n");                 transpose(&matrix2); // pass in matrix2 to inverse function                 printf("\n\n");                        }         else {             printf("\nError. Improper input.\n\n");             break;         }                printf("\n\n");         break;     case 10:         printf("\n\n");         multiply(&matrix1,&matrix2);         printf("\n\n");         break;     case 11:         goto End; // jump past 'goto start'         printf("\n\n");         break;     default:             printf("\nError. Improper input.\n\n");             printf("\n\n");             break; }        goto start;    End:     // free all allocated variables     free(vector1.data);     free(vector2.data);     free(matrix1.row[0].data);     free(matrix1.row[1].data);     free(matrix1.row[2].data);     free(matrix2.row[0].data);     free(matrix2.row[1].data);     free(matrix2.row[2].data);         return 0; } (General)