How do I end a While Loop with 3 conditions - c

while( num != 101 && num != 102 && num != 103 ){
printf( "Enter number: " );
scanf( "%d", &num );
}
I'm making a C program using Loops that accepts numbers from the user until the user inputs the numbers 101, 102, and 103. The above three conditions in while loop is working as an OR operator. If one of the three conditions is met, the while loop stops. What I need is that while loop should be stopped when the three conditions are met. I already tried to use || instead of && but the program just keeps looping. Thank you in advance!!

while( num == 101 && num == 102 && num == 103 ){
printf( "Enter number: " );
scanf( "%d", &num );
}
This is an infintive loop, because that is what you want. It "should be stopped when the three conditions are met".
Num could only justify one condidition. Num couln't be all three values (101 AND 102 AND 103) at the same time. Except you have a quantum computer.

The actual purpose of your program is unclear.
It appears that all three numbers (101, 102 and 103) must be entered by the user before the program will continue.
Typically you would use three separate variables. Are you attempting to simulate a combination lock? If that is the case then the following code seems to work. (Interestingly it is, indeed, a combination lock since the numbers can be entered in any order.)
/* enter the numbers 101, 102 and 103 to exit the while loop
*/
#include <stdio.h>
#include <stdbool.h>
int main (void)
{
printf("\n");
bool flag101 = false;
bool flag102 = false;
bool flag103 = false;
do {
printf("enter number: ");
int num;
scanf("%d", &num);
if (num == 101) {
printf("101 entered\n");
flag101 = true;
}
if (num == 102) {
printf("102 entered\n");
flag102 = true;
}
if (num == 103) {
printf("103 entered\n");
flag103 = true;
}
} while (! (flag101 && flag102 && flag103));
printf("\n");
printf("all three numbers have been entered\n");
return 0;
}

Related

C program to count how many vowels in a list of input words

I need to write a program to count how many vowels (‘a’, ‘e’, ‘i’, ‘o’, ‘u’) in a list of input words. My program reads the words one by one and prints the number of vowels occurring in each word. Each word consists of only alphabets in mixed cases. The program repeats this process until hitting the word “exit” (case-insensitive). In this case, terminate the program after printing the number of vowels in “exit”. After termination, the program shall ignore remaining inputs, if any.
Input: Multiple words spanning across lines.
Each word shall consists of no more than 50 characters.
The words are separated by white spaces.
Output: The number of vowels in each of the input word, separated by newline.
That is, one number on a line.
Example expected input output
Input:
I go to school by BUS
Exit
Output:
1
1
1
2
0
1
2
Another Input:
I
went
apple
school
by
BUS
Exit
Output:
1
1
2
2
0
1
2
I am having problem with "Time limit exceed" and i do appreciate any feedback to my program
when i input:
I go to school by BUS
i got a notification Time limit exceed and an output :
1
1
1
2
0
1
#include <stdio.h>
#include <string.h>
int main(void)
{
char s1[51], ex[5];
int N, i, v, newline=1;
while(newline){
fgets( s1, 51, stdin);
if((s1[0]=='e' || s1[0]=='E')&&(s1[1]=='x' || s1[1]=='X')&&(s1[2]=='i' || s1[2]=='I')&&(s1[3]=='t' || s1[3]=='T')&&(s1[4]=='\0' || s1[4]==' ')){
printf("2\n"); // to check whether the input is Exit
newline=0;
}
else{
N=strlen(s1);
for(i=0;i<N;i++){
if(s1[i]=='a' || s1[i]=='o' || s1[i]=='e' || s1[i]=='i' || s1[i]=='u' || s1[i]=='A' || s1[i]=='O' || s1[i]=='E' || s1[i]=='I' || s1[i]=='U'){
v++; // to calculate the number of vowels
}
if(s1[i+1]==' '){ // if next entry is spacebar, print the number of vowels in the current word and add i so that next loop will start on new word
printf("%d\n", v);
v=0;
i++;
}
else if(s1[i+1]=='\n'){ // if next entry is new line, print the number of vowels in the current word, restart the whole program by exiting the for loop
printf("%d\n", v);
v=0;
newline=1;
break;
}
}
}
}
return 0;
}
You should review few things:
When compare char, case-insensitive, is easy to do like that:
char c1, c2;
if ( toupper(c1) == toupper(c1) ) {
do_something();
}
To exit from a loop, I would use break; instead of return;
The whole code would be this:
#include <stdio.h>
#include <ctype.h>
int isVowel(char c);
int isExit(char* c);
int main(void)
{
char s1[51];
int N, i, v = 0;
int noExit = 1;
while( noExit ){
fgets( s1, 51, stdin);
N=strlen(s1);
for(i=0;i<N;i++) {
if ( isExit(&s1[i]) ) {
printf("2\n");
noExit = 0;
break;
}
else{
if( isVowel(s1[i]) ) {
v++;
}
else if( s1[i]==' ' || s1[i]=='\n' ) {
printf("%d\n", v);
v=0;
}
}
}
}
return 0;
}
int isVowel(char c) {
c = toupper(c);
if( c=='A' || c=='E' || c=='I' || c=='O' || c=='U' )
return 1;
else
return 0;
}
int isExit(char* c) {
if ( (toupper(c[0]) == 'E') && (toupper(c[1]) == 'X') &&
(toupper(c[2]) == 'I') && (toupper(c[3]) == 'T') ) {
return 1;
}
else {
return 0;
}
}
You have an infinite loop. newline will never be 0. and the outer while loop will never exit.
So, you need to change the newline=1 in the last else if condition to newline=0.
In addition, the variable v is not initialized, so you are not getting the first answer correctly. You should set v=0 at the beginning before the while loop starts.

How to reject letter when requesting int in C

When I enter a letter the loop runs infinitely. Does a letter store as a zero when it is input as an int? How can I reject a non digit answer, just I have rejected an answer outside the range?
int main(int argc, const char * argv[]) {
// insert code here...
int categoryToScore;
int categoryScores = 6;
printf("Enter category to save score: ");
scanf("%d", &categoryToScore);
while (categoryToScore >= categoryScores || categoryToScore <= 0) {
printf("Error: invalid command. Enter 1-5 to save to an unused category\n");
printf("Enter category to save score: ");
scanf("%d", &categoryToScore);
}
return 0;
}
Just for background
I want to:
print a request an input that is between 1 and an upper bound
scanf for the input
check if the input is of a correct type and within the correct range
if it isn't then print an error message and go back to 1.
if it is then proceed
You are asking scanf to read a number from standard input. Scanf finds a non-digit character in the standard input and does not remove it from the standard input. Scanf fails and returns 0 (the number of fields successfully processed).
The next time you call scanf, it finds the same character at the start of standard input. So the process repeats indefinitely.
One solution is to read stdin one character at a time.
Another solution is to read (and discard) the one character from stdin before calling scanf again.
int main(int argc, const char * argv[]) {
// insert code here...
int categoryToScore;
int categoryScores = 6;
int scantRetVal;
printf("Enter category to save score: ");
scantRetVal = scanf("%d", &categoryToScore);
if (scantRetVal != 1) {
getchar(); // read and discard one character from stdin
categoryToScore = 0;
}
while (categoryToScore >= categoryScores || categoryToScore <= 0) {
printf("Error: invalid command. Enter 1-5 to save to an unused category\n");
printf("Enter category to save score: ");
scantRetVal = scanf("%d", &categoryToScore);
if (scantRetVal != 1) {
getchar(); // read and discard one character from stdin
categoryToScore = 0;
}
}
return 0;
}
Rather than fix this particular program I will show how to solve ANY similar problem using a concept called an "exit condition".
The idea of an exit condition is that you have an infinite loop and it has various exit conditions. Often there are two exit conditions: one for success and one for an error.
while( true ){ /* infinite loop */
char c = ... /* get the character you want */
if( c < '0' || c > '9' ){
printf( "invalid character, not a digit\n" );
continue; // get another character
}
... /* do whatever you with valid data */
if( c == '3' ) break; /* your exit condition, whatever it is */
if( c == '7' ) exit(0); /* exit the whole program */
}
Note: If you are accepting free form input (numbers and strings), scanf is probably not a good idea. scanf accepts very specific, well-formatted input. So if you ask for a %d, then there better be a %d (decimal number) in the input or you will have problems.
For example, if you accept numbers and strings, you should take everything as strings using fgets or something like that.
Here is a complete program that does what you want:
#include <stdio.h>
#include <stdbool.h>
int main(int argc, const char * argv[]) {
int iMaxScore = 6;
int charInput = 0;
int iInputValue = 0;
while( true ){
printf("Enter category to save score: ");
GetInput:
charInput = getchar();
if( charInput == 10 || charInput == 13 ) goto GetInput; /* ignore enter key */
if( charInput == 'q' ) break;
if( charInput < '0' || charInput > '9' ){
printf( "invalid entry, not a digit %d\n", charInput );
break;
}
iInputValue = charInput - '0';
if( iInputValue > iMaxScore ){
printf( "Error, input value exceeds maximum category %d\n", iMaxScore );
continue; /* try again */
}
printf( "you entered category %d\n", iInputValue );
/* continue ... */
}
return 0;
}

Re-prompting a user until he/she enters a positive integer value greater than 1

I'm solving CS50 (problemset 1) i.e water.c. It asks user to write a program that prompts the user for the length of his or her shower in minutes (as a positive integer) and then prints the equivalent number of bottles of water (as an integer).
1 min of shower = 12 bottles consumed
MAIN PROBLEM: The problem is that we have to ensure that the user inputs a positive number of minutes otherwise it keeps on re-prompting his back to input/scanf statement. As long as he enters he enters length<=0, I can re-prompt him back using while(length<=0) condition but as he enters a character i.e abc123 in input my code keeps on executing. Any solutions??
>
#include <stdio.h>
int main()
{ int length=0;
int min=12;
int bottle=0;
printf("Enter length of his or her shower in minutes");
scanf("%d", &length);
while (length <= 0){
printf("Enter length of his or her shower in minutes");
scanf("%d", &length);
}
bottle= (min*length);
printf("%d", bottle);
return 0;
}
You can solve this by reading a string first, and then extracting any number:
#include <stdio.h>
int main(void)
{
int length = 0;
char input[100];
while(length <= 0) {
printf("Enter length: ");
fflush(stdout);
if(fgets(input, sizeof input, stdin) != NULL) {
if(sscanf(input, "%d", &length) != 1) {
length = 0;
}
}
}
printf("length = %d\n", length);
return 0;
}
Program session:
Enter length: 0
Enter length: -1
Enter length: abd3
Enter length: 4
length = 4
Crucially, I always check the return value from scanf, the number of items successfully converted.
If you don't care about Inputs like 1f then the Above Answers are ok For you, but if you do not want to accept this kind of Input, then the following approach does something like that:
#include<stdio.h>
int checkInput(void);
int main(void){
int number = checkInput();
printf("\nYour number is\t%d\n",number);
return 0;
}
int checkInput(void){
int option,check;
char c;
do{
printf("Please type a number:\t");
if(scanf("%d%c",&option,&c) == 0 || c != '\n'){
while((check = getchar()) != 0 && check != '\n' && check != EOF);
printf("\tI sayed a Number please\n\n");
}else{
if ( option < 1){
printf("Wrong input!\n");
}else{
break;
}
}
}while(1);
return option;
}
Output:
Please type a number: 1f
I sayed a Number please
Please type a number: f1
I sayed a Number please
Please type a number: -1
Wrong input!
Please type a number: 1
Your number is 1
You don't need the first prompt outside the loop because you have already initialised length to zero, so the loop will prompt at least once.
On most platforms other then Wndows, you need to flush stdout to show text not terminated with a newline.
scanf will return so long as a newline character is buffered and %d alone will not consume the newline, so you need to ensure that any remaining characters up to and including the newline are flushed to prevent an endless loop.
It is good practice to check the return value from scanf() since it makes no guaranteed about not modifying its arguments even when a conversion fails.
It is not clear why min is a variable here sine it is initialised but never re-assigned, but presumably that may be the case in the final program?
#include <stdio.h>
int main( void )
{
int length = 0 ;
int min = 12 ;
int bottle = 0 ;
while( length <= 0 )
{
int converted = 0 ;
printf( "Enter length of his or her shower in minutes: " ) ;
fflush( stdout ) ;
converted = scanf( "%d", &length ) ;
if( converted != 1 )
{
length = 0 ;
}
while( (c = getchar()) != '\n' && c != EOF ) { } // flush line buffer
}
bottle = min * length ;
printf( "%d", bottle ) ;
return 0;
}
int min = 0;
do {
printf("Enter minutes: ");
scanf("%i", &min);
} while(min <= 0);
//programs resumes after this.

Difficulty using scanf for input

Can someone help me to solve my problem? I have a problem with %[^\n]. When I try to enter a false input the program loop the warning that I wrote, but if I use %s and I enter my string the next statement is not working properly.
#pragma warning (disable:4996)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char name[30];
char number[12];
int flag, flag1, flag2, flag3;
int i;
printf("Add New Contact\n");
do {
printf("input name [1..30 char]: ");
scanf("%[^\n]", name); fflush(stdin);
if ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z')) {
flag = 1;
}
else {
flag = 0;
printf("First letter of name should be an alphabet (A-Z or a-z)\n");
}
if (strlen(name) > 30) {
flag1 = 0;
printf("Length of name should be between 1 and 30 characters\n");
}
else {
flag1 = 1;
}
} while (flag == 0 || flag1 == 0);
do {
printf("Input phone number[6..12 digits]: ");
scanf("%s", number); fflush(stdin);
for (i = 0; i < strlen(number); i++) {
if (number[i] >= '0' && number[i] <= '9') {
flag2 = 1;
}
else {
flag2 = 0;
}
}
if (flag2 == 0) {
printf("Phone numbers should only contain digits (0-9)\n");
}
if (strlen(number) >= 6 && strlen(number) <= 12) {
flag3 = 1;
}
else {
flag3 = 0;
printf("Length of phone numbers should be between 6 and 12 digits\n");
}
} while (flag2 == 0 || flag3 == 0);
printf("\n");
printf("New contact successfully added!\n");
printf("Press Enter to continue...");
getchar();
getchar();
return 0;
}
Oh by the way, the problem might simply be that the scanf call leaves the newline in the buffer, and if you loop and try again the first character seen will be the newline and scanf should not read any thing.
There are two things you should do: First check what scanf returns, it should return 1 if it read a string. Secondly you should tell scanf to discard any possible leading white-space by adding a space first in the format string: " %[^\n]".
Most scanf formats automatically skips leading white-space, but not when using the "%[" or "%c" formats.
Also, to not worry about writing out of bounds of the array, you should add a length modifier to make sure that scanf doesn't read more input than it can write: " %29[^\n]". If the length of the string is 29 after this, then you should probably read until you reach the end of the line, character by character.
Here is your program fixed:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
// In case you need this -- not needed for this case
void discard_input()
{
char c;
while( ( c = getchar() ) != '\n' && c != EOF );
}
void remove_trailing_newline(char * s)
{
char * ch = s + strlen( s ) - 1;
while( ch != s ) {
if ( *ch == '\n' ) {
*ch = 0;
break;
}
--ch;
}
return;
}
int main(){
char name[30];
char number[12];
int flag, flag1, flag2, flag3;
int i;
printf("Add New Contact\n");
do {
printf("\nInput name [1..30 char]: ");
fgets( name, 30, stdin );
remove_trailing_newline( name );
flag1 = flag = 1;
if ( !isalpha( name[ 0 ] ) ) {
flag = 0;
printf("First letter of name should be an alphabet (A-Z or a-z), found: %s\n", name );
}
// impossible
if (strlen(name) > 30) {
flag1 = 0;
printf("Length of name should be between 1 and 30 characters\n");
}
} while (flag == 0 || flag1 == 0);
do {
printf("\nInput phone number[6..12 digits]: ");
fgets( number, 12, stdin );
remove_trailing_newline( number );
flag2 = flag3 = 1;
int len_phone = strlen( number );
for (i = 0; i < strlen(number); i++) {
if ( !isdigit( number[ i ] ) ) {
flag2 = 0;
}
}
if (flag2 == 0) {
printf("Phone numbers should only contain digits (0-9), found:'%s'\n", number);
}
if ( len_phone < 6 || len_phone > 12) {
flag3 = 0;
printf("Length of phone numbers should be between 6 and 12 digits, found: %d\n", len_phone );
}
} while (flag2 == 0 || flag3 == 0);
printf("\n");
printf( "Name: '%s'\n", name );
printf( "Phone: '%s'\n", number );
printf("New contact successfully added!\n");
printf("Press Enter to continue...");
getchar();
return 0;
}
You can find the program here.
The fixings are more or less interesting, I enumerate they here:
At first, I thought that the problem was that the trailing new line was being left in the input buffer. fflush(stdin) is actually undefined behaviour in C, since the fflush() function is there for output streams. Anyway, I included the code in question 12.26b of the comp.lang.c FAQ, since I think it is interesing to have it as reference. Then, I decided to change scanf() with fgets(). This is due to the scanf() taking spaces as delimiters, so you wouldn't be able to write a complete name, i.e., name and surname. Remember that gets() is not an option, since it writes the input past the limit of the buffer. Actually, fgets() solves this by letting us define a limit of chars to read. The problem is that fgets() also includes the '\n' in the buffer, so, that's why I included the remove_trailing_newline() function. Tricky, isn't it?
You added a condition to check whether the name input had more than thirty chars. Actually, this is impossible to check in your program. First of all, fgets() will read 29 chars + the final char mark (0). Secondly, if you were actually allowing to input more than 30 chars, then the input would be written past the size of the buffer, which is undefined behaviour (crashes in most cases). You would have to use something more complex, like std::string in C++, and then check its length. Or maybe use a third party expandable string for C. Or roll out your own expandable string...
You can decide whether there is an alphabetic char or a digit by using isalpha(c) and isdigit(c) functions.
When you are going to use a value many times, such as strlen(name), then you should precompute it and store it in a local variable. Though a good compiler (its optimizer) will detect this situation and solve it for you, you never know which compiler is going to compile your code, and how advanced it is. Also, there is nothing wrong making things easier for the optimizer.
When you have a situation in which you set a flag for signaling an error condition, it is easier to set it to the "no error" value before checking anything, and solely in case of an error, set it to the "error" value. This will be easier to read, and therefore, to understand.
Hope this helps.

Need help looping magic-number program

I have written the below code and need help understanding why it's not working the way it should. It compiles, however, it isn't running the if-else in my loops. For example, if I were to take out the while loop in my code everything would work fine, however, I want to know how many tries it takes for someone to guess the "magic number" or random number in this case.
#include <stdio.h>
int main()
{
int magicnum = 1234;
int userguess;
int totalguess = 0;
printf("Try to guess a number between 1 and 10000!: ");
scanf("%d", &userguess);
while(totalguess <= 7 && magicnum != userguess);{
if(magicnum == userguess){
printf("Congratulations, You Win!!\n");
if(totalguess = 1){
printf("Wow you did it on your first try!!\n");
}
else(totalguess >= 2); {
printf("Nice one!! It only took you %d tries!\n", totalguess);
}
}
else if(magicnum > userguess){
printf("Too Low try again!!\n");
}
else{
printf("Too High try again!!\n");
}
totalguess++;
}
return 0;
}
I am looking for an output of either someone answering the correct number which is "1234" if they score too high they should see the response of "Too High try again!!", and if they score too low they should see the response of "Too low try again!!. Also, it is supposed to show how many attempts it took them, and if they got it on the first try or not. The max number of attempts a person should be able to do this should be 7.
Problem #1 problem lies in the line
while(totalguess <= 7 && magicnum != userguess);{
Specifically at the semicolon. The above evaluates to the following
// Sit on this line until a condition is met
while(totalguess <= 7 && magicnum != userguess);
// Some block of code which is unrelated to the while loop
{
...
}
The answer is to remove the extraneous semicolon at the end of the while loop:
while(totalguess <= 7 && magicnum != userguess) {
// No semicolon ^
Problem #2 is in the line
if (totalguess = 1){
Where you are actually assigning totalguess to 1. Fix this by changing = (assignment) to == (comparison).
Problem #3 and #4 are in the line
else(totalguess >= 2); {
Not sure how this is even compiling, but you should have an else if rather than an else. And as with the while loop, you have another extraneous semicolon. Remove it.
Lastly, you are only asking for user input once, so the program will loop 7 times without asking for input. Put your scanf inside the main while loop
According to Levi's findings, a solution:
const int magic_num = 1234;
const uint max_num_guess = 7;
uint num_guess = 1 + max_num_guess;
int user_guess;
printf( "Try to guess a number between 1 and 10000!\n" );
for( uint idx = 0; idx < max_num_guess; ++idx )
{
scanf( "%d", &user_guess );
if( magic_num == user_guess ) { num_guess = 1 + idx; idx = max_num_guess; }
else
{
if( magic_num < user_guess ) { printf( "Too High try again!!\n" ); }
else { printf( "Too Low try again!!\n" ); }
}
}
if( num_guess <= max_num_guess )
{
printf( "Congratulations, You Win!!\n" );
if( 1 == num_guess ) { printf( "Wow did it on your first try!!\n" ); }
else { printf( "Nice one!! %d tries!\n", num_guess ); }
}
To #3 it is valid. Consider:
if(false){}
else(printf("Branch!\n"));
{ printf("Done.\n"); }

Resources