Catching the user entering a string when expecting an integer? - c

I am making a program where the user enters two binary numbers and an operation character then I print the output in decimal. I want the while loop to keep the program running until the user enters quit. How can I read if the user enters quit and not an integer value in the scanf? Is there a way to catch this?
#include <stdio.h>
#include <string.h>
int toDecimal(int num);
int main(){
// Define variables
int num1, num2, result = 0;
char op;
char run[4] = "go";
// While loop to rerun program until quit is entered
while(strcmp(run, "quit\n") != 0){
// Reads user input
scanf("%i %c %i", run, &num1, &op, &num2);
printf("\nnum1: %i num2: %i op: %c\n", num1, num2, op);
num1 = toDecimal(num1);
num2 = toDecimal(num2);
printf("\nnum1: %i num2: %i op: %c\n", num1, num2, op);
}
printf("\nGoodbye!\n");
return 0;
}
I believe that I may be able to read everything in as a string and then convert to an integer however I don't know how. Is this a solution I should look into?

How can I read if the user enters quit and not an integer value in the scanf?
There is no good way with scanf(). Instead get user input with fgets() and do not use scanf() until you know why it is bad.
// Read user input
char buf[80]; // Use adequate size input buffer,
while (fgets(buf, sizeof buf, stdin)) {
buf[strcspn(buf, "\n")] = '\0'; // Lop off potential trailing \n
if (sscanf(bufm "%i %c %i", &num1, &op, &num2) == 3) {
printf("\nnum1: %i num2: %i op: %c\n", num1, num2, op);
num1 = toDecimal(num1);
num2 = toDecimal(num2);
printf("\nnum1: %i num2: %i op: %c\n", num1, num2, op);
} else if (strcmp(buf, "quit")== 0) {
break;
} else {
printf("Bad input <%s> ignored\n", buf);
}
}

This is a pretty basic idea , I hope you get the point.You could also use dynamic memory allocation when reading the string.
Basically you read the whole input with fgets and you extract the variables using sscanf.
#include <stdio.h>
#include <string.h>
int main ()
{
int n1,n2;
char arr[1000],oper;
fgets(arr,sizeof(arr),stdin);
while (strcmp(arr,"quit\n")!=0){
if (sscanf(arr,"%d %c %d",&n1,&oper,&n2)==3); /* Scanning for each number and operator and checking input*/
else
printf("wrong input");
/* Code */
fgets(arr,sizeof(arr),stdin);
}
return 0;
}

Related

I'm struggling with scanf with float

I am having some issues with the scanf function.
I am trying to printf a scanf result, but it only returns 0.00000
Can someone help me? Here is my code done so far:
#include <stdio.h>
int main() {
float grade;
char choise;
do {
printf ("Type your grade: ");
scanf("%f", &grade);
printf("Want to continue? s/n: ");
scanf(" %c", &choise);
printf("%s \n", &choise);
printf("%f", &grade);
}while(choise != 'n');
}
printf("%f", &grade); is wrong
try
printf("%f", grade);
But there are many other issues. At the very least, you must check the values returned by scanf, and you should use int main(void) or int main(int argc, char **argv). eg:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
float grade;
char choise;
do {
printf("Type your grade: ");
fflush(stdout);
if( scanf("%f", &grade) != 1 ){
fprintf(stderr, "Invalid input\n");
exit(1);
}
printf("Want to continue? s/n: ");
fflush(stdout);
if( scanf(" %c", &choise) != 1 ){
fprintf(stderr, "Invalid input\n");
exit(1);
}
printf("%c\n", choise);
printf("%f\n", grade);
} while( choise != 'n' );
return 0;
}
If you don't check the value returned by scanf, you don't know if any data was written into the variable. Since neither choise nor grade is initialized, attempting to read those values if scanf did not assign to them is undefined behavior. The behavior is also undefined if the input stream contains a value that cannot be represented as a float (eg, if it is a value greater than FLT_MAX), but that's really just an argument for avoiding scanf rather than a suggestion to try to make scanf usable. You can try to use scanf to make a user friendly interface, but it's really not worth the effort. Much better to simply abort on bad input. (If you want a user friendly interface, I would recommend you are using the wrong language.) See http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html for more details on why you really ought to just avoid scanf completely.
These calls of printf
printf("%s \n", &choise);
printf("%f", &grade);
are incorrect.
In the first call you are trying to output a single character as a string. In the second call you are trying to output a pointer of the type float * as an object of the type float.
Instead you have to write
printf("%c\n", choise);
printf("%f\n", grade);
The lines
printf("%s \n", &choise);
printf("%f", &grade);
are wrong.
They should be
printf("%c \n", choise);
printf("%f", grade);
The %s format specifier should only be used for strings (null-terminated sequences of characters), not individual characters. The expression &choice does not point to a string, as the character sequence is not null-terminated.
Also, the %c and %f format specifiers require values, not addresses, when using them with printf. Only when using them with scanf should you pass an address.

How to parse operations in c?

I decided to refresh my C by wring a simple little program. I tried to read in from a file "myfile.txt", apply operations and print to stdout. The file contains one line:
2 + 3
the output I expect is:
5
but I found this to be much more complicated than I originally expected. At first I tried using getc() but kept getting segfaults, then I tried fscanf() there is no output from addition to stdin except the print statement that prints:
2 1556274040
Why is the output 2 1556274040? And is there a better way to try to apply operations read form a file, like some apply() function that I can use?
Here's my code:
int main()
{
int ans, num1, num2;
char oper;
FILE *pFile;
pFile = fopen("myfile.txt", "r");
if (pFile != NULL) {
fscanf(pFile, "%d", &num1);
fscanf(pFile, "%c", &oper);
fscanf(pFile, "%d", &num2);
printf ("%d %c %d", num1, oper, num2);
if (oper == '+') {
ans = num1 + num2;
printf(ans);
}
fclose(pFile);
}
return 0;
}
printf(ans);
Not a valid syntax to print an int variable.
Try this -
printf("%d\n",ans);
As you ask
you can use fgets instead of using fscanf to read contents of file but make sure you check their return.
Here's a possible solution...
#include <stdio.h>
int main() {
int ans, num1, num2;
char oper;
FILE *pFile;
pFile = fopen("myfile.txt", "r"); // might need to specify binary/text
if (pFile != NULL) {
// fscanf(pFile, "%d", &num1); need spaces in format specifier.
// fscanf(pFile, "%c", &oper);
// fscanf(pFile, "%d", &num2);
// one way to solve...
fscanf(pFile, "%d %c %d", &num1, &oper, &num2);
fclose(pFile); // stopping some errors
printf ("%d %c %d = ", num1, oper, num2);
} // end if
else
puts("fopen returned NULL");
if (oper == '+') {
ans = num1 + num2;
printf("%d",ans);
} // end if
return 0;
} // end main

How to stop a program based on user's input in C

I'm just starting to learn C and I'm having problem with stopping my program based on what the user inputted.
#include <stdio.h>
#include <stdbool.h>
int main()
{
int a;
int b;
char c[5];
printf("Enter the two values you like to compare, type stop to end.\n");
while (c != "stop")
{
scanf_s(" %d %d %s", &a, &b, &c);
if (!(a^b))
{
printf("both are equal\n");
getchar();
}
else
{
printf("both are not equal\n");
getchar();
}
}
printf("Thanks for playing.");
getchar();
return 0;
}
The problem that I'm having is having to put in another variable, c, in my scanf_s. How would I do it so that the user does not have to put in another word after the 2 numbers? Also how can I check if the user only input "stop" so that it will stop the program? Btw the way I have it right now also does not stop the program when I do "10 10 stop". Thanks.
remove & for c in scanf_s(" %d %d %s", &a, &b, &c);
use strcmp to compare strings.
if you need to ignore case while comparing use strcasecmp (for UNIX based systems) and stricmp (for windows).
Use do-while instead of while if you need to run the loop at least once.
Full Working Code:
#include <stdio.h>
#include <string.h>
int main()
{
int a;
int b;
char c[5] = {'\0'};
do {
printf("Enter the two values you like to compare, type stop to end.\n");
scanf("%d%d%s", &a, &b, c);
if (!(a^b))
{
printf("both are equal\n");
getchar();
}
else
{
printf("both are not equal\n");
getchar();
}
}
while (strcmp(c,"stop"));
printf("Thanks for playing.");
getchar();
return 0;
}
while (c != "stop")
You cannot compare strings in C like that, use memcmp() or strncmp() library functions available in string.h. Read about them to know how they can be implemented as condition in while loop.
Also, to get string input, use
scanf_s(" %d %d %s", &a, &b, c); // Remove that litle '&' before 'c'.
NOTE: The function scanf_s returns the number of inputs scanned correctly, you should check that before proceeding with input values.
To get the user to stop without explicitly entering "stop", many ways are there:
1) Use do-while loop and keep asking user if he wants to play more.
2) Use negative numbers input (say -1) to quit.
Use line below to make sure your 'c' scan your string entered.
scanf(" %d %d %s", &a, &b, c);
Edit:
Consider replacing your while with line below to make sure you stop works. Include "string.h"
while (strcmp(c,"stop"))
Here is the fixed version... I have add the comments in the code for understanding...
#include <stdio.h>
#include <string.h>
int main()
{
int a;
int b;
char c[5] = {'\0'};
printf("Enter the two values you like to compare, type stop to end.\n");
while (strcmp(c,"stop"))
{
scanf("%d%d%s", &a, &b, c);
if (!(a^b))
{
printf("both are equal\n");
getchar();
}
else
{
printf("both are not equal\n");
getchar();
}
}
printf("Thanks for playing.");
getchar();
return 0;
}
First, lets correct your program:
&c (third argument to scanf_s) is incorrect. It should be c (because it is already a pointer). According to docs, scanf_s requires sizes to be specified for all %s format strings; therefore, the way you are doing things now, you should have written scanf_s(" %d %d %4s", &a, &b, c);
The program would be much easier to use if you changed your logic to "enter a blank line to exit". You can test this looking at the return value of scanf_s, which will be the number of format strings correctly read from the input.
If you need to ask for strings, then allow either, and look at whatever the user wrote to see whether it was number or string:
#include <stdio.h>
#include <string.h>
int main() {
int a;
int b;
char c[32];
printf("Enter the two values to compare, or type stop to end.\n");
while (fgets(c, 31, stdin) != NULL && strncmp("stop\n", c)) != 0) {
// user did not request to exit and wrote something; maybe 2 numbers
if (sscanf(c, "%d %d", &a, &b) != 2) {
// but he did not write two numbers. Complain and repeat.
printf("please write two numbers to compare, or type stop to end.\n");
continue;
}
if (a == b) {
printf("both are equal\n");
} else {
printf("both are not equal\n");
}
}
printf("Thanks for playing.\n");
return 0;
}
fgets reads whole lines, and you can then try to parse them using sscanf. This has the advantage over common scanf that you can try to parse the same line in different ways, depending on what you find in it. Generally, you do not want to fill your code with getchar(). If you are debugging, your debugger will stop for you. If you are not debugging, you will want to test or use your program with input redirection, and getchar() is simply not needed.
Its because you are using &c instead of just c in scanf_s. Replace that and it should work. Also, c is a string, so, you have to use strcmp instead of !=.
An easier way to write this code would be::
int main()
{
int a;
int b;
char c;
do
{
printf("Would you like to play?\nPress 'Y' for 'Yes' or 'N' for 'No'\n");
scanf( "%c", &c ) ;
/*scanf_s( "%c", &c, 1 ) ; */
if( c != 'Y' && c != 'y' )
break ;
printf("Enter the two values you like to compare\n" ) ;
scanf(" %d %d", &a, &b);
if (!(a^b))
{
printf("both are equal\n");
getchar();
}
else
{
printf("both are not equal\n");
getchar();
}
}while(1) ;
printf("Thanks for playing.");
getchar();
return 0;
}

Switch small program does not let me see result

I am learning the switch statement of C. This is my small program and it runs and does the calculation but doesn't let me see the result of the operation. The black window shows up so that I input the numbers and the operator and then for a fraction of a second shows the result and disappears. Any help is appreciated.
#include <stdio.h>
int main(int argc, char *argv[])
{
int num1, num2, ans=0;
char ch, name;
printf("Enter a value: ");
scanf("%d", &num1);
printf("Enter a second value: ");
scanf("%d", &num2);
printf("Input * To multiply\
+ To add\
- To subtract: ");
scanf(" %c", &ch);
switch(ch)
{
case'*':
ans=num1 * num2;
printf("%d times %i equals: %i",num1,num2,ans);
break;
case'+':
ans=num1+num2;
printf("%i plus %i equals: %d",num1,num2,ans);
break;
case'-':
ans=num1-num2;
printf("%d minus %d equals: %d",num1,num2,ans);
break;
default:
printf("Range numbers");
}
getchar();
return ch;
}
Probably due to output buffering. Add newlines (\n) last in your formatting strings.
As a newbie, you should end all your printf format string with an escaped newline \n, i.e. printf("%i plus %i equals %d\n", num1, num2, ans); (or you should call fflush(stdout); just after the end of the switch before the getch and before all your scanf).

How to validate user input?

In the program written below how i can ensure that only integer value is entered?
And if character is entered the program should convert it to its ASCII equivalent and then add them and show output as number.
Please help me......
#include<stdio.h>
int main(int argc, char **argv)
{
int a,b,c;
printf("enter two numbers:-");
scanf("%d \t %d",&a,&b);
c=a+b;
printf("addition of numbers= %d",c);
}
scanf returns the number of items that it successfully read, so you can check to make sure that it returns the same number that you expect. For example,
if (scanf("%d \t %d", &a, &b) != 2)
{
// handle error
}
Note that \t is a whitespace character, and whitespace is ignored by scanf.
Just to add to what James said.
Dont forget to flush stdin
#include<stdio.h>
int main(int argc, char **argv)
{
int a,b,c;
printf("enter two numbers:-");
if( scanf("%d \t %d",&a,&b) == 2 )
{
c=a+b;
printf("addition of numbers= %d",c);
}
else {
printf("please enter a valid input");
getchar(); // the getchar will clear the stdin otherwise next time you go do
// a scanf it might not work.
}
}

Resources