How to use conditions with numbers and words - c

I've been trying to make this simple program that basically a little conversation. The biggest problem I've run into is that whenever I wanted to ask for the age and if someone wrongly answered with something that it's not a number, but a phrase or a word, instead of it beeing impossible it just assume a value. What can I write so that if someone rights something that is not a number it just repeats the loop?
main (){
printf("Can you tell me your age\n");
scanf("%d",&age );
do{
if ( age < 16) {
printf("You're a child!\n");
}
else if ( age == 17){
printf("Me too, cool! Let's meet.\n");
}
else {
printf("Pretty old! You are dying.\n");
}
} while ((age<=0) && (age>130));
}

To check if a character represents a digit or not, you can use the standard function isdigit().
But in your case with scanf() you can just check for its return value.
You might want to "clean stdin" if you don't know what the user will type.
void clean_stdin(void)
{
int c = 0;
while (c != '\n' && c != EOF)
c = getchar();
}
int main(void)
{
int age;
int scanf_ret;
do
{
printf("Can you tell me your age\n");
scanf_ret = scanf("%d", &age);
clean_stdin();
} while (scanf_ret != 1);
/*
Now we know that age contains a valid number
*/
return (0);
}

On success, scanf() returns the number of items of the argument list successfully filled. We've got only one argument, so we can use this return value in the while loop to continually check it against 1 (a valid input):
#include <stdio.h>
int main() {
int age, temp, status;
printf("Can you tell me your age\n");
status = scanf("%d", &age);
while(status!=1) {
while( (temp=getchar()) != EOF && temp != '\n' ) {};
printf("Invalid input... please enter a number: ");
status = scanf("%d", &age);
}
if ( age < 16) {
printf("You're a child!\n");
}
else if ( age == 17) {
printf("Me too, cool! Let's meet.\n");
}
else {
printf("Pretty old! You are dying.\n");
}
}
Hope this helps.

You need to check what scanf is returning in the if statement,you can modify you code like this:
int main()
{
int age;
printf("Can you tell me your age\n");
scan:
if((scanf("%d",&age ))==1)
{
do{
if ( age < 16) {
printf("You're a child!\n");
}
else if ( age == 17){
printf("Me too, cool! Let's meet.\n");
}
else {
printf("Pretty old! You are dying.\n");
}
} while ((age<=0) && (age>130));
}
else
{
printf("Please enter a number\n");
fflush(stdin);
goto scan;
}
return 0;
}

Related

Run-Time Check Failure #2 - s (C language on Microsoft Visual C++ 2015 (community version))

I have faced this problem : Run-Time Check Failure #2 - S in visual studio 15 . This happen before where I also trying to use array in C language. According to my textbook, what happen to the below code is
char myname[20];
printf("Type your name:");
scanf("%19s", myname);
printf("\n\n%s,Welcome to the class\n", myname);
According to the textbook, if I input my name as for example : Tony Stark, the problem will only scan the Tony and ignore all the thing after the blank space. However, when I try it, it appear Run-Time Check Failure #2.
Also in below code
#include<stdio.h>
int main(void)
{
char name[30];
int seat[30] = { 0 };
int i, seatt, j;
char decision[1];
do
{
printf("Hi, what is your name? ");
scanf("%s", name);
printf("Welcome %s!\n\n", name);
printf("*********************\n");
printf("CINEMA 1 SEATING PLAN\n");
printf("*********************");
for ( i = 0; i < 30; i++)
{
if (i % 5 == 0)
{
printf("\n\n");
}
if (seat[i] == 0)
{
printf("%3d", i);
}
else
{
printf("%3s", "**");
}
}
printf("\n\n*********************");
do
{
printf("\n\nWhich seat do you want? ");
scanf("%d", &seatt);
if (seat[seatt]!=0)
{
printf("Sorry, seat is taken!\n");
for ( j = 0; j < 30; j++)
{
if (seat[j] == 0)
{
printf("Suggest to take seat: %d", j);
break;
}
}
}
} while (seat[seatt] != 0);
++seat[seatt];
printf("\n\nWould you like to make next booking (Y or N)? ");
scanf("%s", decision);
printf("\n\n");
if (decision[0] == 'Y' || decision[0] == 'y')
{
system("cls");
}
} while (decision[0] == 'Y' || decision[0] == 'y');
printf("See you again!\n");
return 0;
}
Everything is ok, until when until the last part where it ask me where to book the next ticket, if I keyin another other than Y, it also appear the same problem.
You are not very careful with respect to stack overflows. In the second code, you use:
char decision[1];
scanf("%s", decision);
The scanf will append a trailing \0 termination character already interfering with some other data on the stack even if you really only input a single character. More disaster is at hand when the user input is longer. Scan with a "%c" format in this case.
What you should do is you should scan in character instead of String
Do:
char decision[1];
scanf("%c", decision);

C Program Looping Incorrectly

I'm just a beginner and I'm trying to use whatever I know to make a simple program that:
Asks the user to input the letter 'S' or 's'. The program loops if 's' is not input. If the user does input 's', the program then
Asks the user to input a number, 1 or 2. The program loops if the incorrect number is input.
The problem I'm having is that after 's' is successfully input and the user is asked to enter a number, if an incorrect number is input (not 1 or 2) the program asks the user to input a letter again from the beginning which is incorrect. The program loops from the very beginning and doesn't work anymore. Can anyone help me fix this please?
#include <stdio.h>
#include <ctype.h>
int function(int num);
int main()
{
char input,ch,temp,c[64],exit;
int i,invalid,num,index,flag,day;
invalid = 0;
num = 0;
size_t length = 0;
index = 0;
flag = 0;
do
{
puts("Enter the letter S to start the program:");
scanf("%c", &input);
while( input!='\n' && (ch=getchar())!='\n' && ch!= EOF);
{
if(isalpha(input)==0)
{
printf("Invalid input. Please input something.\n");
continue;
}
if(input == 'S' || input == 's')
{
printf("\nProgram start.");
while( sscanf(c, "%d", &num) != 1)
{
length = 0;
flag = 0;
num = 0;
printf("\nEnter 1 for Module A. Enter 2 for Module B. Enter here: ");
fgets(c, 63, stdin);
length = strlen(c);
for(index = 0; index < length; ++index)
{
if(c[index] < '0' || c[index] > '9')
{
flag = 1;
break;
}
}
if( flag)
{
printf("\nInvalid character\n");
continue;
}
if( sscanf(c, "%d", &num) != 1)
{
printf("\nNo input detected.");
continue;
}
if(num == 1)
{
printf("\nModule A Selected.\n");
return(0);
}
if(num == 2)
{
printf("\nModule B Selected.\n");
return(0);
}
}
}
else
{
printf("\nInvalid input.");
continue;
}
}
}
while(1);
}
Make the scanf into like this.
scanf(" %c",&input);
Then While getting the input from the user using fgets It will place the new line character into that buffer. So this will lead to fails this condition.
if(c[index] < '0' || c[index] > '9')
{
flag = 1;
break;
}
So make the this condition into like this.
length=strlen(c)-1;// to skip the new line character
Or else to like this.
length=strlen(c);
if ( c[length] == '\n' )
c[length]='\0';
Output After placing this,
Enter the letter S to start the program:
S
Program start.
Enter 1 for Module A. Enter 2 for Module B. Enter here: 1
Module A Selected.
Make this in you code.
if(num == 1)
{
printf("\nModule A Selected.\n");
return(0);
}
else if(num == 2)
{
printf("\nModule B Selected.\n");
return(0);
}
else
{
printf("\nInvalid option\n");
c[0]='\0'; // It is for satisfy the second while loop condition.
continue;
}
Note that the loop:
while( input!='\n' && (ch=getchar())!='\n' && ch!= EOF);
is limited to the one line by the semicolon at the end. The following code is not the body of the loop, despite indentation trying to pretend that it is.
Also note that getchar() returns an int, not a char; you cannot reliably assign the result to a char and then test it for EOF. Depending on the platform, you will either never detect EOF at all or you will misdetect EOF when some other character (often ÿ, y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS) is typed. You must use int ch;.
Here. I fixed the problem using the following code. This way the code does the following:
Scans letters 'S' or 's'. Keeps looping if these are not entered.
Scans either number 1 or 2. Keeps looping until either number is entered and then exits.
The program does not loop from the very beginning (by outputting "Enter 'S' to start program), if any number other than 1 or 2 in entered in part 2 of the program. This was the problem originally.
The following is the correct code:
#include <stdio.h>
#include <ctype.h>
int function();
char input,temp,c[64],ch,exit;
int i,invalid,num,index,flag,start;
start = 0;
invalid = 0;
num = 0;
size_t length = 0;
index = 0;
flag = 0;
int main()
{
do
{
puts("Enter the letter S to start the program: ");
scanf("%c", &input);
while( input!='\n' && (ch=getchar())!='\n' && ch!= EOF);
{
if(isalpha(input)==0)
{
printf("Invalid input. Please input something.\n");
continue;
}
if(input == 'S' || input == 's')
{
printf("\nProgram start.");
start = 1;
if(start == 1)
{
function();
return(0);
}
}
else
{
printf("\nInvalid input.");
continue;
}
}
}
while(1);
}
int function()
{
while( sscanf(c, "%d", &num) != 1)
{
length = 0;
flag = 0;
num = 0;
printf("\nEnter 1 for Module A. Enter 2 for Module B. Enter here: ");
fgets(c, 63, stdin);
length = strlen(c);
length --;
for(index = 0; index < length; ++index)
{
if(c[index] < '0' || c[index] > '9')
{
flag = 1;
break;
}
}
if( flag)
{
printf("\nInvalid character\n");
continue;
}
if( sscanf(c, "%d", &num) != 1)
{
printf("\nNo input detected.");
continue;
}
if(num == 1)
{
printf("\nModule A Selected.\n");
return(0);
}
else if(num == 2)
{
printf("\nModule B Selected.\n");
return(0);
}
else
{
printf("\nInvalid option\n");
c[0]='\0'; // It is for satisfy the second while loop condition.
continue;
}
}
}

How to prevent non-numeric input in C?

I wrote a small C program which will get an input from the user and check if the input is even or odd.
#include<stdio.h>
int main()
{
int n;
printf("Enter an integer number: ");
scanf("%d",&n);
if(n%2 == 0)
{
printf("\n%d is an EVEN number.\n",n);
}
else
printf("\n%d is an ODD number.\n",n);
return 0;
}
but when I enter an alphabet or a symbol, it shows the output as 0 and says input is EVEN. How can I prevent user from entering alphabets and symbols? What's the easiest way to do that?
You have to check the return value of scanf. From the documentation:
Return Value
Number of receiving arguments successfully assigned, or EOF if read failure occurs before the first receiving argument was assigned.
Applied to your code:
#include <stdio.h>
#include <stdlib.h>
int
main()
{
int n;
printf("Enter an integer number: ");
if (scanf("%d", &n) != 1)
{
printf("This is not a number.\n");
return EXIT_FAILURE;
}
else if (n % 2 == 0)
{
printf("\n%d is an EVEN number.\n", n);
return EXIT_SUCCESS;
}
else
{
printf("\n%d is an ODD number.\n", n);
return EXIT_SUCCESS;
}
}
Simply check the return value of scanf - it'll tell you how many format objects were successfully parsed. In this case, it'll return 1 if it could parse an int, and 0 if it couldn't.
If the input is an integer, then scanf() will return 1 so you can check
if (scanf("%d", &integer) != 1)
invalidInput();
to ask the user again you should know that there could be characters left in the stdin that need to be read so you can flush them with getchar() so a complete function would be
int scanint(const char *const message)
{
int value;
printf("%s > ", message);
while (scanf("%d", &value) != 1)
{
int chr;
printf("\tinvalid input...\n");
do {
chr = getchar();
} while ((chr != EOF) && (chr != '\n'));
printf("%s > ", message);
}
return value;
}
and you can use it like this
int main()
{
int value = scanint("please input an integer");
printf("your input was: %d\n", value);
return 0;
}
I can give you two approaches:
very easy — check for return value of scanf(). 1 indicates success (integer read) and 0 if any non-integer is put in there (or EOF on EOF).
by writing code for it:
#include <ctype.h>
#include <stdlib.h>
int isNumeric (const char * s)
{
if (s == NULL || *s == '\0' || isspace(*s))
return 0;
char * p;
strtod (s, &p);
return *p == '\0';
}
Now in this case your scanf has to take a string from user and then pass that string to the function isNumeric().

How do I store (scanf) a randomly generated number? ( Code inside)

This is the code i used to generate the number:
printf("%d\n", rand()%10);
I am creating a card game HiLo. I want to know how to store the number generated from that and then make the user guess wether the next number is going to be higher or lower than the previous. After that, another number is generated and not stored just yet. I want to compare the new number with the old number too see if the user is correct (alot points) and then store the new number.
You just want to use a variable. All variables may include alphabetic characters, as well as numeric characters, however the first character must be alphabetic. The concept of creating a variable is that you are creating an area of temporary storage for the successful operation of your program. Any areas of code using a particular variable are considered to be dependent on it, and variables work in "scopes". Scopes are started using the { character and are ended using the } character. Any variables declared between these characters are usable only within those characters, and not outside of them, as they do not exist except within those characters.
I have created an example of the program I believe you are trying to write in order to demonstrate the software programming practices involved in such a task.
The example is shown below:
#include <stdio.h>
#include <string.h>
#define LENGTH_OF_BUFFER 100
int main( int argc, char **argv )
{
int prevRandomNumber = rand() % 10;
int continuePlaying = 1;
while( continuePlaying == 1 )
{
int randomNumber = rand() % 10;
int userSelection = 0;
char lineBuffer[LENGTH_OF_BUFFER];
printf( "Previous random number %d\n", prevRandomNumber );
while( userSelection == 0 )
{
printf( "higher or lower?" );
gets( lineBuffer );
if ( strcmp( "higher", lineBuffer ) == 0 )
{
userSelection = 1;
printf( "You selected higher!\n" );
}
else if ( strcmp( "lower", lineBuffer ) == 0 )
{
userSelection = -1;
printf( "You selected lower!\n" );
}
else
{
printf( "Sorry, I didn't understand you, please check your input and try again!\n" );
}
}
if ( userSelection == 1 )
{
if ( randomNumber > prevRandomNumber )
{
printf( "Correct, you really are a marvel!\n" );
}
else
{
printf( "Incorrect, I pity you!\n" );
}
}
else if ( userSelection == -1 )
{
if ( randomNumber < prevRandomNumber )
{
printf( "Correct, you really are a marvel!\n" );
}
else
{
printf( "Incorrect, I pity you!\n" );
}
}
printf( "Number was %d\n", randomNumber );
printf( "Care to play again?\n" );
gets( lineBuffer );
prevRandomNumber = randomNumber;
if ( strcmp( "yes", lineBuffer ) != 0 )
{
continuePlaying = 0;
}
}
}
I hope this helps...
int number = rand()%10;
int nextNumber;
char choice;
while(choice != 'Q' && choice != 'q')
{
printf("Current Number is : %d",number);
printf("\nYou want to guess the next number : ");
printf("\nPress L if number will be greater than current number ");
printf("\nPress S if number will be smaller than current number ");
printf("\nPress Q if you want to quit playing : ");
Printf("\n\nEnter your choice : ")
scanf("%c",&choice);
nextNumber = rand()%10;
if(choice == 'L' || choice == 'l')
{
if(nextNumber > number)
{
printf("\nYour Guess is Right...");
}
else
{
printf("\nYour Guess is wrong...");
}
}
else if(choice == 'L' || choice == 'l')
{
if(nextNumber < number)
{
printf("\nYour Guess is Right...");
}
else
{
printf("\nYour Guess is wrong...");
}
}
else
{
printf("\nYour choice is invalid. Try Again...");
}
number = nextNumber;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(){
char* bet, cmd;
long random_number, new_random_number;
while (1)
{
srand(time(NULL));
random_number = rand();
printf("%d\n", random_number);
printf("bet if the next number is bigger (+) or lower (-): ");
scanf("%s",bet);
srand(time(NULL));
new_random_number = rand();
printf("%d\n", new_random_number);
/* TODO - you might want to put that into a function some how */
if ( bet[0] == '+')
{
if ( new_random_number >= random_number ) /* user is correct */
{
printf("yeah! you are right\n");
printf("\nlet's play again!!\n");
continue;
}
else
{
printf("trololol :P That was wrong\n");
printf("\nlet's play again!!\n");
continue;
}
}
if ( bet[0] == '-')
{
if ( new_random_number < random_number ) /* user is correct */
{
printf("yeah! you are right\n");
printf("\nlet's play again!!\n");
continue;
}
else
{
printf("trololol :P That was wrong\n");
printf("\nlet's play again!!\n");
continue;
}
}
}
}
/* vim: set et sw=4 ts=4: */

Logic in detecting int in C

I would appreciate some help with this. I'm trying to create this simple program that repeatedly loops asking for the user to enter in an int. If he enters an int, it exits but if he enters something else or bigger than int (ex.4gs4r33) it will loop again asking to enter an int. This is what I have tried, and it's not working. It says it's an int even if it's not.
#include<stdio.h>
unsigned int findInt();
int main() {
printf("Please input an int.\n");
findInt();
}
unsigned int findInt() {
char input;
long num = 0;
int b = 0;
do {
scanf("%c", &input);
if (isdigit(input)){
num = num*10+input+'0';
b = 1;
}
else if (input == '\n')
b = 1;
else
b = 0;
} while(input != '\n');
if (b == 1)
printf("Great!\n");
else{
printf("Not an int \n");
findInt();
}
return 0;
}
Two possible approaches. One would be to modify your code:
b = 1; // start off with good intentions…
do {
scanf("%c", &input);
if (isdigit(input)){
num = num*10+input -'0'; // *** SUBTRACT '0', don't add it!
}
else if (input != '\n') {
b = 0;
break; // *** break when you find non-digit
}
} while (input != '\n');
Two changes: getting the math right as you compute the integer, and fixing the logic (so you break out of your loop when you find a non digit character)
Second approach:
char buf[100];
char intAsString[100];
fgets(buf, 100, stdin);
sscanf(buf, "%d", num);
sprintf(intAsString, "%d\n", num);;
if(strcmp(buf, intAsString) == 0 ) {
printf("yay - you entered an integer!\n");
}
I'm sure you can figure out how that works.
update a complete code snippet that solves the issue of "loop logic" as well: you call the findInt function once from the top level, and it keeps going until you get the int. Note - in order for this to work properly, I read the entire input at once (rather than one at a time), then pick off the characters one by one using sscanf (and updating the pointer manually). It has a number of advantages - not least of which is that you start with a fresh input every time you call findInt, instead of having the rest of the input buffer that still needs reading (and which was giving rise to "no,no,no,great!" - as you would keep reading the bad input until you got to the newline, and accept that...)
#include<stdio.h>
#include <ctype.h>
unsigned int findInt();
int main() {
findInt();
}
unsigned int findInt() {
char input;
char buf[100];
char *temp;
long num = 0;
int b = 0;
printf("please enter an int:\n");
fgets(buf, 100, stdin);
temp = buf;
do {
sscanf(temp++, "%c", &input);
if (isdigit(input)){
num = num*10+input-'0';
b = 1;
}
else if (input == '\n')
{
b = 1;
break;
}
else {
b = 0;
break;
}
} while(input != '\n');
if (b == 1)
printf("Great! %d is an integer!\n", num);
else{
printf("Not an int \n");
findInt();
}
return 0;
}
In the else branch - i.e. not a digit or a newline - you set b to 0. Now if a digit DOES follow you reset that to 1.
You'll probably want to break or somehow record the permanent failure instead of just continuing.
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
void findInt(){
int x;
bool ok;
do{
char buff[32], *endp;
long long num;
ok = true;//start true(OK)
printf("Enter a number: ");
fgets(buff, sizeof(buff), stdin);
//strtoll : C99
x=(int)(num=strtoll(buff, &endp, 0));//0: number literal of C. 10 : decimal number.
if(*endp != '\n'){
if(*endp == '\0'){
printf("Too large!\n");//buffer over
while('\n'!=getchar());
} else {
printf("Character that can't be interpreted as a number has been entered.\n");
printf("%s", buff);
printf("%*s^\n", (int)(endp - buff), "");
}
ok = false;
} else if(num > INT_MAX){
printf("Too large!\n");
ok = false;
} else if(num < INT_MIN){
printf("Too small!\n");
ok = false;
}
}while(!ok);
}
,

Resources