I will use this small part of code in my assignment but there are some problems. When I don't use fflush(stdin) it doesn't scan the basetype. But when I use fflush(stdin) it scans the basetype but the scanf inside the while loop doesn't continue to take the characters from the buffer. For example when I enter 2A... Please help.
#include <stdio.h>
#include <math.h>
int main() {
int operation, basetype, number1;
char num1;
printf("Please enter the number of the operation you would like to perform:");
printf("\n1. Bitwise OR\n2. Bitwise NOT\n3. Bitwise COMPARE\n4. Exit");
scanf("%d", &operation);
if (operation == 1) {
printf("You chose Bitwise OR operation.");
printf("\nPlease enter the first number:");
scanf(" %c", &num1);
fflush(stdin);
printf("\nPlease specify the base(10/16):");
scanf("%d", &basetype);
if (basetype == 10) {
while (num1 != 10) {
number1 = num1 - '0';
if (number1 >= 1 && number1 <= 9) {
printf("ok");
} else
printf("not ok");
scanf("%c", &num1);
}
}
}
return 0;
}
fflush(stdin); has undefined behavior, do not use it to attempt to flush the standard input buffer. You could instead write:
{ int c; while ((c = getchar()) != EOF && c != '\n') continue; }
You should also decide whether you read a number in num1 or a digit. "%c" is for reading a single character, "%d" to read a number in decimal format.
There is a scanf format tailored for your needs: %i converts a number encoded in a user specified base, 8, 10 or 16 depending on the initial characters, just like the C source code syntax for integer literals.
Here is a simplified program that can deal with hexadecimal input entered with a 0x prefix, such as 0x40 for 64:
#include <stdio.h>
#include <math.h>
int main(void) {
int operation, number1, number2, result;
printf("Please enter the number of the operation you would like to perform:\n"
"1. Bitwise OR\n"
"2. Bitwise NOT\n"
"3. Bitwise COMPARE\n"
"4. Exit\n");
if (scanf("%i", &operation) != 1)
return 1;
if (operation == 1) {
printf("You chose Bitwise OR operation.\n");
printf("Please enter the first number: ");
if (scanf("%i", &number1) != 1)
return 1;
printf("Please enter the second number: ");
if (scanf("%i", &number2) != 1)
return 1;
result = number1 | number2;
printf("%d (0x%x) | %d (0x%x) = %d (0x%x)\n",
number1, number1, number2, number2, result, result);
}
return 0;
}
the following proposed code:
cleanly compiles
contains embedded comments about problems with the code
is organized to clearly show what each part of the code is doing
for Bitwise_OR operation clearly shows the code does nothing, especially not a bitwise OR operation
and now the proposed code:
#include <stdio.h> // scanf(), printf(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
//#include<math.h>
enum
{
Bitwise_OR = 1,
Bitwise_NOT,
Bitwise_COMPARE,
Exit
};
int main( void )
{
char operation;
int basetype;
int number1;
char num1;
puts("Please enter the number of the operation you would like to perform:");
printf( "%s",
"1. Bitwise OR\n"
"2. Bitwise NOT\n"
"3. Bitwise COMPARE\n"
"4. Exit");
if( 1 != scanf(" %c",&operation) )
{
perror( "scanf for operation failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
switch( operation )
{
case Bitwise_OR: //<-- bitwise OR never performed
printf("You chose Bitwise OR operation.");
printf("\nPlease enter the first number:");
if( 1 != scanf(" %c",&num1) )
{
perror( "scanf for first number failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
//fflush(stdin);
printf("\nPlease specify the base(10/16):");
if( 1 != scanf("%d", &basetype) )
{
perror( "scanf for base failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
switch(basetype)
{
case 10:
while(num1 != 10) //<-- user entering 0x0A is extremely unlikely
{
number1=num1-'0'; //<-- what if num1 not '0'...'9'
if(number1>=1 && number1<=9)
{
printf("ok");
}
else
printf("not ok");
// either retry first digit or get second digit
scanf(" %c",&num1); //<-- leading space to consume 'white space'
}
break;
case 16:
break;
default:
puts( "base must be 10 or 16" );
break;
} // end switch()
break;
case Bitwise_NOT:
break;
case Bitwise_COMPARE:
break;
case Exit:
break;
default:
break;
} // end switch()
return 0;
} // end function: main
Related
So in this C code the program will give an error message that says "Invalid grade" and it asks the user to enter the grade again if the entered grade is >100 or <0, but this only happens once. If the user enters an invalid grade again the program returns black rather than giving the error message again and asking user to reenter the grade. How can I fix this?
#include <stdio.h>
#include <math.h>
int main()
{
double grade;
printf("Enter the student's grade: ");
scanf("%lf",&grade);
if (grade<0 || grade>100)
{
printf("Invalid grade\n");
printf("Enter the student's grade: ");
scanf("%lf", &grade);
}
if (grade>=90 && grade<=100)
printf("A");
if (grade>=80 && grade<=89)
printf("B");
if (grade>=70 && grade<=79)
printf("C");
if (grade>=60 && grade<=69)
printf("D");
if (grade<60 && grade>=0)
printf("F");
return 0;
}
This type of user-input validation code is where a do-while loop is idiomatic:
int scanned;
do
{
printf("Enter a grade between 0 and 100 (inclusive): ");
scanned = scanf(" %lf", &grade);
}
while(scanned != 1 && (grade < 0.0 || grade > 100.0));
Also note:
I check the return value of scanf to ensure that it's the same value as the number of format specifiers in the string. This tells me that scanf succeeded.
I put a space before the format specifier in the scanf format string. This consumes all whitespace left in the buffer prior to the new input.
You don't need to combine conditions with && operator.
if (grade >= 90)
{
printf("A");
}
else if (grade >= 80)
{
printf("B");
}
else if (grade >= 70)
{
printf("C");
}
else if (grade >= 60)
{
printf("D");
}
else if (grade >= 0)
{
printf("F");
}
Try this one:
#include <stdio.h>
#include <math.h>
int main()
{
double grade;
printf("Enter the student's grade: ");
scanf("%lf",&grade);
while (grade<0 || grade>100)
{
printf("Invalid grade\n");
printf("Enter the student's grade: ");
scanf("%lf", &grade);
}
if (grade>=90 && grade<=100)
printf("A");
if (grade>=80 && grade<=89)
printf("B");
if (grade>=70 && grade<=79)
printf("C");
if (grade>=60 && grade<=69)
printf("D");
if (grade<60 && grade>=0)
printf("F");
return 0;
}
This is hard to do with generality. scanf was not really meant for interactive programmes; see why not use scanf. The accepted answer of using a loop is good, and checking the return value is important. However, it fails for many edge cases; I've expended and covered some of them here as an addendum.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <math.h>
int main(void) {
int scanned, garbage, is_infected;
double grade;
const double max_grade = 100;
input:
printf("Enter a grade between 0 and %.0f (inclusive): ", max_grade);
/* Ignore leading whitespace. */
scanned = scanf(" %lf", &grade);
/* Ignore up to EOL for future input. */
is_infected = 0;
while((garbage = getchar()) != '\n' && garbage != EOF)
if(!isspace(garbage)) is_infected = 1;
if(is_infected) { fprintf(stderr, "Non-numerical input.\n"); goto input; }
/* `scanned` can be EOF, 0, or 1. */
switch(scanned) {
case EOF: /* EOF could mean different things. */
if(ferror(stdin)) { /* It could mean an error. */
/* ISO C doesn't strictly define whether bumped to `errno`. */
if(!errno) errno = EILSEQ;
perror("input");
} else { /* Or it could mean EOF. */
fprintf(stderr, "Premature EOF.\n");
}
return EXIT_FAILURE;
case 1: /* Successfully matched a double. */
/* `isnan` is C99; C90, `grade != grade` is true by IEEE754, which some
compilers relax. */
if(isnan(grade) || grade < 0.0 || grade > max_grade) {
fprintf(stderr, "Out of range [0, %.0f].\n", max_grade);
goto input;
}
grade = fabs(grade); /* For -0.0. */
break;
default: /* 0, unlikely (impossible?) because of clear of `stdin`. */
fprintf(stderr, "No number.\n");
goto input;
}
printf("number: %f\n", grade);
return 0;
}
How do I make my if statement ask the user to try again if the input is a negative number or a letter?
struct foodstuff {
float amount;
};
void add(struct foodstuff *tmpAdd) {
printf("Write amount: ");
scanf("%f", &tmpAdd->amount);
while (tmpAdd->amount != 0) {
if (tmpAdd->amount < -1 || isalpha(tmpAdd->amount)) {
printf("Type in a valid number!\n");
printf("Write amount: ");
getchar();
scanf("%f", &tmpAdd->amount);
getchar();
}
else {
scanf("%f", &tmpAdd->amount);
getchar();
}
}
};
I think you can rephrase your code to use a do loop instead:
do {
printf("Enter a positive number with no characters:\n");
int result = scanf("%f", &tmpAdd->amount);
while (tmpAdd->amount <= 0 || result != 1);
Note that I have removed the call to isalpha(), which acts only a single character at a time. Instead, I propose just checking that the entered number is a valid float and that it is greater than zero. If scanf does not succeed to read in a valid float, then its return value would be not be 1 and the loop would repeat. And the same is the case for entering a valid float which is a negative number.
As chux said, you could first read the input with fgets() and then parse it.
Like
char buff[100], *ptr;
float f;
while(fgets(buff, sizeof(buff), stdin)!=NULL)
{
buff[strlen(buff)-1]='\0';
f=strtof(buff, &ptr);
if(errno==ERANGE)
{
printf("\nPossible overflow.");
errno=0;
continue;
}
if(f<0 || *ptr!='\0')
{
printf("Type in a valid number!\n");
continue;
}
tmpAdd->amount=f;
printf("\n%f", f);
}
Here, fgets() is used to read the input on each iteration. fgets() will return NULL upon error.
The
buff[strlen(buff)-1]='\0';
is done because fgets() will read in the trailing \n into buff as well. We modify that \n to be the \0 character denoting the end of string with buff[strlen(buff)-1]='\0';.
strtof() is used to extract the value from buff.
It is in stdlib.h.
In case buff has something other than numbers, the number part would be converted and returned by strtof() and the ptr pointer would be made to point to the first non-numeric part of buff.
So if the first character in the string pointed to by ptr is the \0 character, there were no non-numeric parts in buff.
If the input value was too large or too small to be accommodated in a float, errno would be set to ERANGE. You need to include errno.h for that.
If overflow (or underflow) occurred, we set errno to 0 and continue.
And (tmpAdd->amount<-1) would be false even if tmpAdd->amount were -1 and -1 is negative. You need (tmpAdd->amount<0) instead.
Also, your loop would exit only when tmpAdd->amount becomes 0. You could simply do
tmpAdd->amount=0;
if that would do.
Otherwise, you can add a
if(f==0)
{
break;
}
at the end of the while loop.
I did some changes to my code, it looks like this now:
printf("Write amount: ");
scanf("%f", &(tmpAdd + index)->amount);
getchar();
do {
if (tmpAdd->amount <= -1 || isalpha(tmpAdd->amount != 0)) {
printf("Type in a valid number!\n");
printf("Write amount: ");
scanf("%f", &(tmpAdd + index)->amount);
getchar();
}
else if (isdigit(tmpAdd->amount >= 0)) {
scanf("%f", &(tmpAdd + index)->amount);
//getchar();
}
} while (tmpAdd->amount <= -1 || isalpha(tmpAdd->amount != 0));
};
Main looks like this:
int main (void) {
int input, noFood = 0;
int flag = 1;
printf("Welcome to the shopping list manager. \n\n");
struct foodstuff food1;
while (flag == 1) {
printf("1 - add food\n");
printf("2 - print shopping list\n");
printf("3 - end\n\n");
printf("What do you want to do? ");
scanf("%d", &input);
clear();
switch (input) {
case 1: add(&food1, noFood); noFood++; break;
case 2: print(&food1, noFood); break;
case 3: printf("\nExiting program\n"); flag = 0; break;
default: printf("Please enter a valid choice\n");
}
}
return 0;
}
And the output like this:
Output
The only problem remaining is that when I want to add another item (add food) for the second time and I type a letter or a negative number, it doesn't run through the if statements.
Beginner to C and doing an assignment for a course. Fixed what I think needed to be fixed, but my menu will only go to part A, but not B, C, or D. It quits fine as well. No errors, wondering what is wrong with my code.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define PAUSE system("pause")
#define CLS system("cls")
#define FLUSH flush()
// Prototype Functions Here
void highestNumber(int, int, int);
void lowestNumber(int, int, int);
void displayAverage(int, int, int);
void displayMenu();
void flush();
char getUserChoice();
main() {
char userSelection;
int number1 = 0, number2 = 0, number3 = 0;
do {
userSelection = getUserChoice(); // Gets/DisplaysMenu
switch (userSelection) {
case 'A': // Enter a number
printf("Enter a number 1: ");
scanf("%i", &number1);
printf("Enter a number 2: ");
scanf("%i", &number2);
printf("Enter a number 3: ");
scanf("%i", &number3);
break;
case 'B': // Display Highest Number Entered
printf("In Case B");
highestNumber;
break;
case 'C': // Display Lowest Number entered
printf("In Case C");
lowestNumber;
break;
case 'D': // Display Average of Numbers entered
printf("In Case D");
displayAverage;
break;
case 'Q': // Quit the program
printf("You have quit the program\n");
PAUSE;
break;
default: // Invalid Selection
printf("Invalid selection...try again!\n");
PAUSE;
break;
} // end switch
} while (userSelection != 'Q');
PAUSE;
} // end of main
//==============
void highestNumber(int number1, int number2, int number3) {
if (number1 > number2 && number1 > number3) {
printf("The highest number is: %i", number1);
}
else if (number2 > number1 && number2 > number3) {
printf("The highest number is: %i", number2);
}
else if (number3 > number2 && number3 > number1) {
printf("The highest number is: %i", number3);
}
} //end highest number
void lowestNumber(int number1, int number2, int number3) {
if (number1 < number2 && number1 < number3) {
printf("The lowest number is: %i", number1);
}
else if (number2 < number1 && number2 < number3) {
printf("The lowest number is: %i", number2);
}
else if (number3 < number2 && number3 < number1) {
printf("The lowest number is: %i", number3);
}
} // end lowest number
void displayAverage(int number1, int number2, int number3) {
int average = (number1 + number2 + number3) / 3;
printf("The average of the three numbers you entered is: %i", average);
} // display average
void displayMenu() {
CLS;
printf("\n===============================\n");
printf("========== MAIN MENU ==========\n");
printf("===============================\n");
printf("A. Enter a number\n");
printf("B. Display Highest Number entered\n");
printf("C. Display Lowest Number entered\n");
printf("D. Display Average of Numbers entered\n");
printf("Q. Quit the program\n");
printf("Enter your choice: ");
} // end displayMenu
void flush() {
while (getchar() != '\n');
} // end flush
char getUserChoice() {
char result;
displayMenu();
scanf("%c", &result); FLUSH;
result = toupper(result);
return result;
} // end getUserChoice
the following code should perform as you want.
Caveat: there may be some details that you would like to modify such as uncommenting the calls to getchar()
The following code has a number of constraints built it, like must enter the 3 numbers before trying to do any operations on those numbers.
The following code does not use non-portable calls to the shell.
the data is kept locally in the main() function and passed to each of the sub functions that need it.
Notice the function that changes the data is passed pointers to the data so the sub function can change that data.
useless macros were eliminated
the function: flush() was renamed for clarity as to what it does
appropriate error checking added
commented out unneeded if() statements
expanded flushStdin() to allow for either EOF or '\n'
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
// Prototype Functions Here
void enterNumber (int*, int*, int*); // pass address so function can update
void highestNumber (int, int, int);
void lowestNumber (int, int, int);
void displayAverage(int, int, int);
void displayMenu ( void ); // corrected prototypes
void flushStdin ( void );
char getUserChoice ( void );
int main( void ) // only two valid signatures for main()
// this is one of them
{
char userSelection;
int number1; // added local data variables
int number2;
int number3;
int gotSelections = 0; // so cannot try to work with uninitialized data
do
{
userSelection = getUserChoice(); // Gets/DisplaysMenu
switch (userSelection)
{
case '1': // Enter a number
enterNumber( &number1, &number2, &number3 ); // pass expected parameters
gotSelections = 1;
break;
case '2': // Display Highest Number Entered
if( gotSelections )
{ // then data initialized
highestNumber( number1, number2, number3 ); // pass expected parameters
}
else
{ // else tried to pass unitialized data
printf( "must enter numbers before gathering Statistics\n" );
}
break;
case '3': // Display Lowest Number entered
if( gotSelections )
{ // then data initialized
lowestNumber( number1, number2, number3 ); // pass expected parameters
}
else
{ // else tried to pass unitialized data
printf( "must enter numbers before gathering Statistics\n" );
}
break;
case '4': // Display Average of Numbers entered
if( gotSelections )
{ // then data initialized
displayAverage( number1, number2, number3 );
}
else
{ // else tried to pass unitialized data
printf( "must enter numbers before gathering Statistics\n" );
}
break;
case 'Q': // Quit the program
printf("You have quit the program\n");
//system( "pause" );
break;
default: // Invalid Selection
printf("Invalid selection...try again!\n");
//system( "pause" );
break;
} // end switch
flushStdin();
//getchar();
} while (userSelection != 'Q');
//system( "pause" );
//flushStdin();
getchar();
} // end of main
void enterNumber(int * pNumber1, int *pNumber2, int *pNumber3)
{
printf("Enter a number 1:\n ");
if( 1 != scanf("%i", pNumber1) )
{
fprintf( stderr, "scanf for number1 failed" );
flushStdin();
getchar();
exit( EXIT_FAILURE );
}
printf("Enter a number 2:\n ");
if( 1 != scanf("%i", pNumber2) )
{
fprintf( stderr, "scanf failed for number2" );
flushStdin();
getchar();
exit( EXIT_FAILURE );
}
printf("Enter a number 3:\n ");
if( 1 != scanf("%i", pNumber3) )
{
fprintf( stderr, "scanf for number3 failed" );
flushStdin();
getchar();
exit( EXIT_FAILURE );
}
} //end enter number
void highestNumber(int number1, int number2, int number3)
{
if (number1 > number2 && number1 > number3)
{
printf("The highest number is: %i\n", number1);
}
else if (number2 > number1 && number2 > number3)
{
printf("The highest number is: %i\n", number2);
}
else //if (number3 > number2 && number3 > number1)
{
printf("The highest number is: %i\n", number3);
}
} //end highest number
void lowestNumber(int number1, int number2, int number3)
{
if (number1 < number2 && number1 < number3)
{
printf("The lowest number is: %i\n", number1);
}
else if (number2 < number1 && number2 < number3)
{
printf("The lowest number is: %i\n", number2);
}
else //if (number3 < number2 && number3 < number1)
{
printf("The lowest number is: %i\n", number3);
}
} // end lowest number
void displayAverage(int number1, int number2, int number3)
{
int average = (number1 + number2 + number3) / 3;
printf("The average of the three numbers you entered is: %i\n", average);
} // display average
void displayMenu()
{
//system( "cls" );
puts( "\033[H \033[J"); // \033 is octal value for 'escape'
printf("\n===============================\n");
printf("========== MAIN MENU ==========\n");
printf("===============================\n");
printf("1. Enter a number\n");
printf("2. Display Highest Number entered\n");
printf("3. Display Lowest Number entered\n");
printf("4. Display Average of Numbers entered\n");
printf("Q. Quit the program\n");
printf("Enter your choice: ");
} // end displayMenu
void flushStdin()
{
int ch;
while ( (ch = getchar()) != EOF && '\n' != ch );
} // end flush
char getUserChoice()
{
char result;
displayMenu();
if( 1 != scanf(" %c", &result) )
{
fprintf( stderr, "scanf for menu entry failed" );
flushStdin();
getchar();
exit( EXIT_FAILURE );
}
flushStdin();
//getchar();
result = (char)toupper((int)result);
return result;
} // end getUserChoice
This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 6 years ago.
I will try to explain the issue here.
I have written this code that accepts various types of inputs:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
int main()
{
int number;
printf("press <ENTER> to continue...");
while( getchar() != '\n' );
char *p, s[100];
int n=0;
printf("enter a number: ");
while (fgets(s, sizeof(s), stdin))
{
n = strtol(s, &p, 10);
if (p == s || *p != '\n')
{
printf("Invalid integer, please try again: ");
}
else
break;
}
printf("You entered: %d\n", n);
printf("Enter an integer between 10 and 20: ");
scanf("%d", &number);
while (1)
{
if (number < 10 || number > 20)
{
printf("Invalid value, 10 < value < 20: ");
scanf("%d", &number);
}
else
{
break;
}
}
printf("You entered: %d\n", number);
//part 3
double decpart;
printf("Enter a floating number num: ");
char buf[100];
int len;
char *endptr;
while (1)
{
fgets(buf,sizeof(buf),stdin);
len = strlen(buf)-1;
// right strip spaces (replace by linefeed like fgets ends the input)
while(len>0)
{
len--;
if (buf[len]==' ')
{
buf[len]='\n';
}
else
{
break;
}
}
double floatnum = strtod(buf,&endptr);
if (endptr[0]!='\n')
{
printf("Invalid floating point number, enter again: ");
}
else
{
int intpart = (int)floatnum;
double decpart = floatnum - intpart;
if (decpart == 0.000000){
printf("Invalid floating point number, enter again: ");
}
else
{
printf("Number entered = %.2f\n", floatnum);
break;
}
}
}
double floatnum1;
printf("Enter a floating point number between 10.00 and 20.00: ");
scanf("%lf", &floatnum1);
while (1)
{
if (floatnum1 < 10.00 || floatnum1 > 20.00)
{
printf("Invalid value, 10.000000 < value < 20.000000: ");
scanf("%lf", &floatnum1);
}
else
{
break;
}
}
printf("You entered: %0.2lf\n", floatnum1);
printf("End of tester program for milestone one!\n");
return 0;
}
Problem occurs on Part 3 of this code. I see on screen Enter a floating number num: and immediately without waiting for user input it prints Invalid floating point number, enter again:
This is not the case if I just run part3(commented here in code as //part3) independently, it just works fine.
Any idea, why that is happening?
The reason for this behaviour lies in the usage of scanf followed by fgets
scanf reads a number from standard input, and stops as soon as it encounters a non-digit character, which is the newline in this case.
Next fgets reads a whole line. But now there's still the single newline in the input, which satisfies fgets even though this is only an empty line.
When you skip over whitespace and finally check for a newline, endptr only points to a \0 character. Thus the message
Invalid floating point number, enter again:
To fix this, you must first skip whitespace before reading further with fgets.
I'm trying to make a binary calculator that terminates the the program when q is entered. As a result I made a variable called quit to act as the flag q is entered. However when I made the scanf for the variable q it seems to take away split the inputs up when q is not pressed. for example, if I enter 110 + 110 I get:
110 + 110 = 1000
as if it's doing 10 + 110.
The input has to be all in one line. The format of the input is always going to be:
Operand operator Operand
Which is why I have the:
scanf(" %s %c %s",Binary1, &op, Binary2);
on my code. However if the user input is just q or Q it terminates the program.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
double convertDouble(char Bin []);
double convertBinary(double theAns);
double calculate(double num1,double num2,char op);
main(void) {
char op;
float num1,num2;
char quit;
double n1,n2,ans;
double binAns;
char Binary1[20];
char Binary2[20];
char Input[100];
char myChar;
int i = 0;
// quit = 'k';
while (quit != 'q'){
printf("Enter an expression using binary numbers or Q to quit: ");
// scanf("%s", &quit);
if(quit == 'q' ){
exit(EXIT_SUCCESS);
}else{
}
scanf(" %s %c %s",Binary1, &op, Binary2);
/* while(Binary1[i] > 49 || Binary2[i] > 49){
if(Binary1[i] >= 'q' || Binary1[i]<= 'Q' ){
exit(0);
quit = 'q';
}else{
printf("please enter binary: ");
scanf("%s %c %s\n",&Binary1, &op, &Binary2);
}
i++;
} */
// quit[0] = Binary1[0];
printf("quit = %c\n", quit);
printf("Binary1 =%s\n", Binary1);
printf("op =%c\n", op);
printf("Binary2 =%s\n", Binary2);
n1 = convertDouble(Binary1);
n2 = convertDouble(Binary2);
ans = calculate(n1,n2,op);
binAns = convertBinary(ans);
// printf("value of n1 = %f\n", n1);
// printf("value of n2 = %f\n", n2);
// printf("value of binAns = %f\n", binAns);
// printf("ans = %f", ans);
printf(" = %f\n",binAns);
} // end of while
printf("quit = %c\n", quit);
printf("Binary1 =%s\n", Binary1);
printf("op =%c\n", op);
printf("Binary2 =%s\n", Binary2);
printf("quit");
exit(EXIT_SUCCESS);
}
Note:
More info about my program: the reason why I have the input binaries as strings was because it needs to convert them to a double. It does this in a different function called convertDouble which is not pasted here. It calculates the answer in the function calculate(also not pasted). The answer is converted to a binary in the convertBinary function and then is displayed.
Example of How it's supposed to run
Enter an expression using binary numbers or Q to quit: 1101.001 * 101.1101
= 1001100.0100101
Enter an expression using binary numbers or Q to quit: 0.0000000001 * 0.0000000001
= 0.00000000000000000001
Enter an expression using binary numbers or Q to quit: 0.111 * 1000.0
= 111.0
Enter an expression using binary numbers or Q to quit: 11.0 * 11.0
= 1001.0
Enter an expression using binary numbers or Q to quit: 11.11 + 11.11
= 111.1
Enter an expression using binary numbers or Q to quit: 101.1 / 10.0
= 10.11
Enter an expression using binary numbers or Q to quit: 1001.11 - 11.01
= 110.1
Enter an expression using binary numbers or Q to quit: q
Keep code as simple as possible, keep the minimum number of variables and functions required for functionality.
Think carefully about each requirement of the program, treat them as individual small problems ...
Like this ...
#include <stdio.h>
#include <stdlib.h>
#define BUFLEN 32
double convertToDouble(const char *chars) {
return strtod(chars, NULL);
}
double calculateAnswer(double left, char operator, double right) {
switch (operator) {
case '<': return left < right; break;
case '>': return left > right; break;
case '=': return left == right; break;
case '*': return left * right; break;
case '/': return left / right; break;
}
/* do something */
return -1;
}
int main(int argc, char *argv[]) {
char buffer[BUFLEN*2];
printf("Enter an expression using binary numbers or Q to quit: ");
while (fgets(buffer, BUFLEN, stdin)) {
char left[BUFLEN] = {0},
right[BUFLEN] = {0},
operator = 0;
if(sscanf(buffer, "%s %c %s\n", left, &operator, right)) {
if (!operator) {
if (left[0] == 'q' || left[0] == 'Q') {
printf("Bye!\n");
break;
}
}
printf("%s %c %s = %f\n",
left, operator, right,
calculateAnswer(
convertToDouble(left),
operator,
convertToDouble(right)));
} else {
/* do something */
}
printf("Enter an expression using binary numbers or Q to quit: ");
}
return 0;
}
Note that, this code is not meant to be correct, it's an approximation of the requirements you describe without putting in too much effort.
Much more importantly, it's easy to understand.
Ctrl+C is standard way to terminate console program. But if you want to use 'q' as terminate signal, you can do the following:
char line[128];
float a, b;
char op;
while(true) {
printf("Enter an expression using binary numbers or q to quit: ");
if( gets(line) ) {
if( strcmp(line, "q") == 0 || strcmp(line, "Q") == 0 ) {
printf("See you later");
break;
}
if( sscanf(line, "%f %c %f", &a, &op, &b) != 3 ) {
printf("Error: wrong expression. Please try again");
continue;
}
...
}
}
You can read line of text (function getline or gets_s) and parse it (function sscanf). Try something like this:
char buffer[128];
int nbParsedItems;
printf("Enter an expression using binary numbers or Q to quit: ");
gets_s(buffer, 127);
if (buffer[0] == 'q' || buffer[0] == 'Q')
return;
nbParsedItems = sscanf(buffer, " %s %c %s", Binary1, &op, Binary2);
if (nbParsedItems == 3) /* in other cases you should ask user to enter request again */
{
/* calculate */
}