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;
}