Thread: Help with fflush(stdin)

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    35

    Help with fflush(stdin)

    here is my code, it allows an equation such as 5+(6-2)*2^3/4-10 to be solved using order of operations, but i heard that the fflush(stdin) function is incorrect to use. what should i be using instead?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #define string_size 100
    
    
    char input_string[string_size];
    void RemoveSpaces(char *source);
    double solve(char *equation_s);
    
    
    int main (void)
    {
    int option;
    double result;
    	do
        	{
    		system("cls");
    		printf("Basic Arithmetic Calculator\n");
    		printf("Enter an equation to solve\n");
    		fflush(stdin);
    		gets_s(input_string, string_size);
    		RemoveSpaces(input_string);
    		solve(input_string);
    		result = atof(input_string);
    		printf("\nAnswer: %.4f\n",result);
    		printf("\nDo you want to do another operation?\n1) Yes 2) No\n");
    		scanf("%d",&option);
    	}
    	while (option ==1);
    	system("cls");
    return(0);
    }
    void RemoveSpaces(char *source)//disregards any spaces 
    {
    	char temp_string[string_size];
    	int i,j,size;
    	size = strnlen_s(source,string_size);
    	temp_string[0] = source[0];
    	j = 1;
    	for (i=1;i<=size;i++)
    	{
    		// if subtraction and preseading charitor is an operation, then change to adding a negitive number.
    		if ((source[i] == '-') &&! ((temp_string[j-1] == '*') || (temp_string[j-1] == '/') || (temp_string[j-1] == '+') || (temp_string[j-1] == '^')))
    		{
    			temp_string[j] = '+';
    			j++;
    		}
    		// remove all spaces
    		if (source[i] == ' ')
    		{
    		}
    		else
    		{
    			temp_string[j] = source[i];
    			j++;
    		}
    	};
    	strcpy_s(source,string_size,temp_string);
    }
    
    
    int exist_paren(char *equation_s) //check for parentheses
    {
    	int length,i, rc=0;
    	length=strnlen_s(equation_s,string_size);
    	for(i=0; i<length; i++) // checks for parentheses and returns a 1. if no parentheses found, returns a 0
    	{
    		if((equation_s[i] == '(' )||(equation_s[i]== ')' ))
    		{
    		rc=1;
    		break;
    		}
    	}
    	return (rc);
    }
    
    
    int exist_expon(char *equation_s) //check for exponents
    {
    	int length,i, rc=0;
    	length=strnlen_s(equation_s,string_size);	
    	for(i=0; i<length; i++) // checks for carrot
    	{
    		if(equation_s[i] == '^' )
    		{
    		rc=1; 
    		break;
    		}
    	}
    	return (rc); //if found, returns a 1. if not found returns a 0
    }
    
    
    
    
    int exist_mult(char *equation_s) //check for multiplication and division
    {
    	int length,i, rc=0;
    	length=strnlen_s(equation_s,string_size);	
    	for(i=0; i<length; i++) // checks for carrot
    	{
    		if((equation_s[i] == '*' )||(equation_s[i] == '/' ))
    		{
    		rc=1; 
    		break;
    		}
    	}
    	return (rc); //if found, returns a 1. if not found returns a 0
    }
    
    
    
    
    int exist_add(char *equation_s) //check for addition and subraction
    {
    	int length,i, rc=0;
    	length=strnlen_s(equation_s,string_size);
    	for(i=0; i<length; i++)
    	{
    		if(equation_s[i] == '+' )
    		{
    		rc=1; 
    		break;
    		}
    	}
    	return (rc); //if found, returns a 1. if not found returns a 0
    }
    
    
    double solve_paren(char *equation_s)
    {
    int open_paren=0, close_paren=0, i;
    double result;
    char paren_string[string_size], temp_string1[string_size],temp_string2[string_size];
    	for (i=0; i<strnlen_s(equation_s,string_size); i++) //continues until i = the length of the string entered
    	{
    		if(equation_s[i] == '(' )
    		{
    			open_paren = i;  //searches for open parentheses, and stores position in open_paren
    		}
    		if(equation_s[i] == ')' )
    		{
    			close_paren = i; //searches for close parentheses, and stores position in closes_paren
    			break;
    		}
    	}
    	strncpy_s(paren_string, string_size, &equation_s[open_paren+1], close_paren- open_paren-1);			
    	result=solve(paren_string);	
    	//changes a double negative to a positive	
    	if(result<0)  //checks to see if number inside parentheses is negative
    	{
    		if(equation_s[open_paren-1] =='-') //checks if result is to be negated
    		{
    			result = result *-1;   // changes to a positive
    			open_paren -=1;   // erases negative sign
    		}
    	}					
    	sprintf(temp_string1,"%lf", result); // converts results (double) into an array and stores it in temp_string1	
    	strcpy(temp_string2,&equation_s[close_paren+1]); //copies remainder of string after closing parenthese
    	strcpy(&equation_s[open_paren],temp_string1);
    	i = strnlen_s(equation_s, string_size); // i is length of string size in equation_s 
    	strcpy(&equation_s[i],temp_string2);
    	return result;
    }
    
    
    double solve_expon(char *equation_s)
    {
    int last_op= strnlen_s(equation_s,string_size), first_op=0, carrot=0, i;
    double result, r1, r2;
    char base[string_size],exponent[string_size], temp_string1[string_size], temp_string2[string_size];
    	// Find left operand for exponent 
    	// Will be between first_op and carrot
    	for (i=0; i<strnlen_s(equation_s,string_size); i++)
    	{
    		if((equation_s[i]=='+')||(equation_s[i]=='*')||(equation_s[i]=='/'))
    		{
    			first_op = i+1;
    		}
    		if (equation_s[i]=='^')
    		{
    			carrot = i;
    			break;
    		}
    
    
    	}	
    	// Find right operand for exponent
    	// will be between carrot and last_op
    	for (i=carrot+1; i < strnlen_s(equation_s,string_size); i++)
    	{
    		if((equation_s[i]=='+')||(equation_s[i]=='*')||(equation_s[i]=='/'))
    		{
    			last_op=i-1;
    			break;
    		}
    	}
    	strncpy_s(base, string_size, equation_s+first_op, carrot - first_op);
    	r1= atof(base);
    	strncpy_s(exponent, string_size, equation_s+carrot+1, last_op - carrot);
    	r2= atof(exponent);
    	result = pow(r1,r2);	
    	sprintf(temp_string1,"%f", result); // converts results (double) into an array and stores it in temp_string1
    	strcpy_s(&temp_string2,string_size,&equation_s[last_op+1]); //copies string in equation_s and stores it in temp_string2
    	strcpy_s(&equation_s[first_op],string_size, &temp_string1);
    	i = strnlen_s(equation_s, string_size); // i is length of string size in equation_s 
    	strcpy_s(&equation_s[i], string_size, temp_string2);
    	return result;
    }	
    
    
    double solve_mult(char *equation_s)
    {
    int last_op= strnlen_s(equation_s,string_size), first_op=0, operation=0, i;
    double result, r1, r2;
    char operand1[string_size],operand2[string_size], temp_string1[string_size], temp_string2[string_size];
    
    
    	for (i=0; i<strnlen_s(equation_s,string_size); i++)
    	{
    		if(equation_s[i]=='+') //looks for + sign and stores position
    		{
    			first_op = i+1;
    		}
    		if ((equation_s[i]=='*')||(equation_s[i]=='/'))
    		{
    			operation = i;
    			break;
    		}
    
    
    	}
    	for (i=operation+1; i < strnlen_s(equation_s,string_size); i++)
    	{
    		if((equation_s[i]=='+')||(equation_s[i]=='*')||(equation_s[i]=='/'))
    		{
    			last_op=i-1;
    			break;
    		}
    	}
    	strncpy_s(operand1, string_size, equation_s+first_op, operation - first_op);
    	r1= atof(operand1);
    	strncpy_s(operand2, string_size, equation_s+operation+1, last_op - operation);
    	r2= atof(operand2);
    	if(equation_s[operation]=='*')
    	{
    		result = r1*r2;
    	}
    	else
    	{
    		result = r1/r2;
    	}
    	sprintf(temp_string1,"%f", result); // converts results (double) into an array and stores it in temp_string1
    	strcpy_s(&temp_string2,string_size,&equation_s[last_op+1]); //copies string in equation_s and stores it in temp_string2
    	strcpy_s(&equation_s[first_op],string_size, &temp_string1);
    	i = strnlen_s(equation_s, string_size); // i is length of string size in equation_s 
    	strcpy_s(&equation_s[i], string_size, temp_string2);
    	return result;
    }	
    
    
    double solve_add(char *equation_s)
    {
    int last_op= strnlen_s(equation_s,string_size), first_op=0, operation=0, i;
    double result, r1, r2;
    char operand1[string_size],operand2[string_size], temp_string1[string_size], temp_string2[string_size];
    
    
    	for (i=0; i<strnlen_s(equation_s,string_size); i++)
    	{
    		if(equation_s[i]=='+')
    		{
    			operation = i;
    			break;
    		}
    	}
    	for (i=operation+1; i < strnlen_s(equation_s,string_size); i++)
    	{
    		if(equation_s[i]=='+') //finding next + sign
    		{
    			last_op=i-1;
    			break;
    		}
    	}
    	strncpy_s(operand1, string_size, equation_s+first_op, operation - first_op);
    	r1= atof(operand1);
    	strncpy_s(operand2, string_size, equation_s+operation+1, last_op - operation);
    	r2= atof(operand2);
    	if(equation_s[operation]=='+')
    	{
    		result = r1+r2;
    	}
    	else
    	{
    		result = r1-r2;
    	}
    	sprintf(temp_string1,"%f", result); // converts results (double) into an array and stores it in temp_string1
    	strcpy_s(&temp_string2,string_size,&equation_s[last_op+1]); //copies string in equation_s and stores it in temp_string2
    	strcpy_s(&equation_s[first_op],string_size, &temp_string1);
    	i = strnlen_s(equation_s, string_size); // i is length of string size in equation_s 
    	strcpy_s(&equation_s[i], string_size, temp_string2);
    	return result;
    }	
    
    
    double solve(char *equation_s)
    {
    double result=0;
    	while(exist_paren(equation_s)) //check for parentheses
    	{	
    		result= solve_paren(equation_s); //if parentheses are in equation, goes to solve_paren function
    	}
    	while(exist_expon(equation_s)) // checks for carrot
    	{
    		result=solve_expon(equation_s); // if carrot is in equation, goes to slove_expon
    	}
    	while(exist_mult(equation_s))
    	{
    		result = solve_mult(equation_s);
    	}
    	while(exist_add(equation_s))
    	{
    		result = solve_add(equation_s);
    	}
    	return result;
    }
    line 20 is my fflush function. without it, my program only runs correctly once, and when i choose 1 to enter another operation, the answer printed just turns to 0.0000 and doesn't allow for me to input another string.

  2. #2
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Fact - Beethoven wrote his first symphony in C

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    My first suggestion would be to go through the code and comment out any "fflush(stdin)" statements. The first one I can see seems completely unwarranted. Then run your program and see if it works as expected.

    If not, if it seems to get "hung up" somewhere, look into that bit of code.

    A common culprit of this effect is the input being line-buffered. If, for example, the program asks you to enter a number, the stream isn't flushed to the input until the it sees a newline character (generally speaking - there are exceptions). But in that scenario, the user has actually entered two quantities: the number, and a newline character. The number would be taken, but the newline would float around the input buffer, waiting to be consumed by the next function that checks the input buffer for characters. But you had that code ready to receive a fresh character from the user, so that next command would seem to have been skipped!

    Usually, when you know that there might be characters floating around the input stream, not yet read by your program (and in danger of being picked up by following commands), you can eat up those characters one by one with a quick loop.

    Code:
    while(getchar() != '\n')
        ;
    That code eats any characters in the input buffer, one by one, until a newline is eaten. If that happens, it would typically signal the end of a string, leaving the input buffer fresh and ready for new input.

    The semi-colon on the next line gives an empty command (it's a null statement), because nothing is required of this "while()" loop other than what contained in the argument. The null statement is there to keep the beat, and let the "while()" loop it's in know that something (even if it was nothing) had happened. It could easily be placed right after the closing parenthesis of the "while()" loop - I just placed it there so its usage would be obvious.

    ---

    Or, to summarize, study and run this code:

    Code:
    #include <stdio.h>
    
    int main(void)
    {
        int x,y;
    
        printf("Enter a single character:  ");
    
        x = getchar();  /* reads the single character entered */
        y = getchar();  /* reads the newline sitting in the input buffer */
    
        printf("x = %c\n",x);
        if(y == '\n')
            printf("<newline>\n");
    
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie Question - fflush(stdin) & fpurge(stdin) on Mac and PC
    By tvsinesperanto in forum C Programming
    Replies: 34
    Last Post: 03-11-2006, 12:13 PM
  2. fflush(stdin);?!?!
    By AmeenR in forum C++ Programming
    Replies: 5
    Last Post: 12-16-2003, 09:46 AM
  3. fflush(stdin);
    By ygfperson in forum C++ Programming
    Replies: 2
    Last Post: 08-11-2002, 06:23 PM
  4. fflush(stdin)
    By RyeDunn in forum C Programming
    Replies: 24
    Last Post: 07-18-2002, 09:07 PM
  5. ascii 10 in the stdin after fflush(stdin)??
    By Kev2 in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 06-03-2002, 03:53 PM