I made a simple (and ugly) program to check the password that user inputs for uppercase, lowercase, number and the dollar sign. the problem is that my printf in the beginning of my do while loop repeats itself awkwardly while the scanf doesn't even stop it, and that repetition depends on the input of the user. i put some comments to explain the code, and i'll do some screen shots to show you what i mean by printf repeating itself.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<ctype.h>
int main(){
char pass[10];
int i,t,x,y,z;
t=y=z=0;
do{
printf("Enter a password it needs to have an uppercase letter a lowercase one, a number and a $ sign: ");
scanf(" %c", pass);
//here i test for upper case, letter by letter
for(i=0;i<10;i++){
if(isalpha(pass[i])){
if(isupper(pass[i])){
t++;
}
}
}
//here i test for lower case, letter by letter
for(i=0;i<10;i++){
if(isalpha(pass[i])){
if(islower(pass[i])){
y++;
}
}
}
//here i test for number, letter by letter
for(i=0;i<10;i++){
if(isdigit(pass[i])){
z++;
}
}
//here i look for the dollar sign
for(i=0;i<10;i++){
if(pass[i]=='$'){
x++;
}
}
printf("\n");
//if all the tests were true the variables t,x,y and z would not be 0
}while(t==0 || x==0 || y==0 || z==0);
}
the first display of the code works fine:
enter image description here
however as you will see in this picture, when i enter a bad password the printf repeats:
enter image description here
and the repeating of printf depends on how much the user enters:
enter image description here
even when i enter a good password, the printf repeats itself a bunch of times before the code ends:
enter image description here
i assume the problem is with the for loops in bedded in the do while loop, but i just can't find where exactly is the problem and why printf repeats so weirdly
The main issue is with:
scanf(" %c", pass);
This tries to scan in a single char. To scan in a string use:
scanf("%9s", pass);
The 9 puts a limit on how many chars can be inputted to avoid overflow. 10 is not used because you need to leave room for the end-of-string marker ('\0').
Some other improvements:
do{
// Move here to reset each time
t = y = z =0;
printf("Enter a password it needs to have an uppercase letter a lowercase one, a number and a $ sign: ");
// Should always test the result of scanf
if (1 != scanf("%9s", pass)) {
// Some error
break;
}
// Combine all the for loops
for (i = 0; pass[i]; i++) {
if (isupper(pass[i])) {
t++;
}
else if (islower(pass[i])) {
y++;
}
else if (isdigit(pass[i])) {
z++;
}
else if (pass[i] == '$'){
x++;
}
}
printf("\n");
//if all the tests were true the variables t,x,y and z would not be 0
} while (t==0 || x==0 || y==0 || z==0);
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 9 months ago.
#include <stdio.h>
void print_instructions(){
printf("You will need to input a letter to guess,\n");
printf("Then let the player see the screen, and make guesses.\n");
}
int main(){
char input;
print_instructions();
printf("What letter will the player guess? ");
scanf("%c", &input);
printf("The letter is '%c' (ascii %d)\n", input, input);
int asterisk = 1;
while(asterisk <= 10){
printf("*\n");
asterisk++;
}
int attemptNum = 1;
int z;
while(attemptNum <= 10){
char guess;
printf("What is guess #%d? ", attemptNum);
scanf("%c", &guess);
if(guess <= 96){
printf("Your guess must be a valid letter!\n");
}
else if(guess < input){
printf("Not quite! Guess later in the alphabet.\n");
}
else if(guess > input){
printf("Not quite! Guess later in the alphabet.\n");
}
else{
printf("Congratulations! You got the letter right!\n");\
break;
}
attemptNum++;
}
}
I think I did nothing wrong using while, but I keep having an error like this:
What did I do wrong?
I have no idea why while repeats itself twice on the odd numbers. Is it something to do with the data structure?
There is no issue with while, but with your scanf - it's reading enter from the buffer that you confirmed input with. try scanning like this to clear the enter
scanf("%c\n", &guess);
Because every time you press the enter button on the keyboard, the enter itself will be also seen as a character \n. Its ASCII code is 10, which is invalid for your condition if(guess<=96). Your problem isn't related with the while loop at all.
To solve this problem:
Use getchar() to "absorb" \n
Use fflush(stdin) to clear all characters remained
I have written this simple program, which is supposed to calculate the factorial of a number entered by the user. The program should ask the user to stop or continue the program in order to find the factorial of a new number.
since most of the time user don't pay attention to CapsLock the program should accept Y or y as an answer for yes. But every time I run this program and even though I enter Y/y , it gets terminated !
I googled and found out the problem could be due to new linecharacter getting accepted with my character input so, I modified the scanf code from scanf("%c", &choice); to scanf("%c ", &choice); in order to accommodate the new line character , but my program is still getting terminated after accepting Y/y as input.
Here is the code . Please if possible let me know the best practices and methods to deal with these kinds of issues along with the required correction.
#include<stdio.h>
#include"Disablewarning.h" // header file to disable s_secure warning in visual studio contains #pragma warning (disable : 4996)
void main() {
int factorial=1;//Stores the factorial value
int i; //Counter
char choice;//stores user choice to continue or terminte the program
do {//Makes sure the loop isn't terminated until the user decides
do{
printf("Enter the no whose factorial you want to calculate:\t");
scanf("%d", &i);
} while (i<0);
if (i == 0) //calculates 0!
factorial = 1;
else {//Calculates factorial for No greater than 1;
while (i > 0) {
factorial = factorial*i;
i--;
}
}
printf("\nThe factorialof entered no is :\t%d", factorial);//prints the final result
printf("\nDo you want to continue (Y/N)?");
scanf("%c ", &choice);
} while (choice =="y" || choice =="Y"); // Checks if user wants to continue
}
I'm a beginner in programming and I'm running this code in visual studio 2015.
Just modify your scanf like following:
printf("\nDo you want to continue (Y/N)? ");
scanf(" %c", &choice); //You should add the space before %c, not after
also you should use:
} while (choice == 'y' || choice == 'Y'); // Checks if user wants to continue
NOTE:
Simple quote ' is used for characters and double quote " is used for string
Your second-last line has a string literal "y", which should be a character literal i.e. 'y':
} while (choice =="y" || choice =="Y");
This should be:
} while (choice =='y' || choice =='Y');
Also, your scanf() doesn't consume whitespace. Add a space before %c to make it ignore newlines or other spaces:
scanf(" %c", &choice);
Try doing the following even after the correction there are still some bugs in the code
In your code if you type 'Y' and recalculate a factorial it gives wrong answer as
int factorial is already loaded with the previous value
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
using namespace System;
using namespace std;
int calculateFactorial(int i);
int main()
{
int i;
char choice;
do{
printf("Enter the no whose factorial you want to calculate:\t");
scanf("%d", &i);
printf("\n The factorial of entered no is :\t %d", calculateFactorial(i));
printf("\n Do you want to continue (Y/N)?");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
return 0;
}
int calculateFactorial(int i) {
int factorial = 1;
if (i == 0){
factorial = 1;
}else {
while (i > 0){
factorial = factorial*i;
i--;
}
}
return factorial;
}
I am rewriting the Guessing Game code from 'C Programming for Absoulute Beginners' to verify that the user has entered in a digit, using the isdigit() function.
The rest of the code works, in terms of error checking; but the moment that the user enters in a non-digit, the code goes into an infinite loop.
#include <stdio.h>
#include <stdlib.h>
#define NO 2
#define YES 1
main()
{
int guessGame;
guessGame = 0;
int iRandomNum = 0;
int iResponse = 0;
printf("\n\nWould you like to play \"The Guessing Game\"?\n\n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
do{
if(guessGame == YES){
iRandomNum = (rand() % 10) + 1;
printf("\nGuess a number between 1 and 10:\n\n ");
scanf("%d", &iResponse);
if(!isdigit(iResponse)){
printf("\nThank you\n");
printf("\nYou entered %d\n", iResponse);
if(iResponse == iRandomNum){
printf("\nYou guessed right\n");
printf("\nThe correct guess is %d!\n", iRandomNum);
printf("\nDo you wish to continue? \n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
} else {
printf("\n\nSorry, you guessed wrong\n");
printf("\nThe correct guess was %d!\n", iRandomNum);
printf("\n\nDo you wish to continue? \n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
}
}
else {
printf("\nYou did not enter a digit\n");
printf("\n\nPlease enter a number between 1 and 10:\n\n");
scanf("%d", &iResponse);
}
}
else {
printf("\nThe window will now close. Try again later!\n");
exit(0);
}
}while(guessGame != NO);
}
The code goes into infinite loop as scanf() is unable to read an integer. The character you entered remains in the keyboard buffer.No more reading of integers is possible as long as the character is present in the buffer. scanf() simply returns the number of items read as 0 each time. Hence,the program does not wait for the user to enter data and infinite loop results.
scanf() returns number of items successfully read. So,you can simply check for the return value of scanf(), if its 1 then scanf() has correctly read an integer.
check = scanf("%d", &iResponse);
if(check == 1){
printf("\nThank you\n");
printf("\nYou entered %d\n", iResponse);
and flush the buffer if wrong input is entered
else {
while (getchar() != '\n'); //flush the buffer
printf("\nYou did not enter a digit\n");
printf("\n\nPlease enter a number between 1 and 10:\n\n");
//scanf("%d", &iResponse);
}
no need to ask for input here, while loop will continue and prompt for input in the beginning
Trying taking the input in the form of string .. also u will have to compare the input in the form 'number' :)
The problem is that when i type any character except for y or n it display this message two times instead to one)
This program is 'Calculator'
Do you want to continue?
Type 'y' for yes or 'n' for no
invalid input
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main ()
{
//program
//first to get two numbers
//second to get choice
int x=0,y=0,n=0;
char choice;
//clrscr(); does no work in devc++
system("cls"); //you may also use system("clear");
while(x==0)
{
puts("\t\tThis program is 'Calculator'\n\n");
puts("Do you want to continue?");
puts("Type 'y' for yes or 'n' for no ");
scanf("%c",&choice);
x++;
if(choice=='y')
{
y++;
puts("if this worked then we would continue to calculate the 2 no");
}
else if(choice=='n')
exit(0);
else
{
puts("invalid input");
x=0;
}
}
getch();
}
`
it looping twice because enter(\n) character is stored in buffer use scanf like this(add space before %c)
scanf(" %c",&choice);
That is because of the trailing new line after you enter y or n and hit enter key.
Try this out:
scanf("%c",&choice);
while(getchar()!='\n'); // Eats up the trailing newlines
If you input any character other than 'y' or 'n', control enters the :
else
{
puts("invalid input");
x=0;
}
block, which resets x to 0, Now the loop condition :
while(x == 0)
is true and hence it enters the loop again.
Also you may want to skip the trailing newline character while reading like :
scanf(" %c", &choice );
This program runs into an infinite loop despite providing 'n' as an input,to exit the while loop.
What could be the issue ?
#include<stdio.h>
main()
{
int num,p=0,q=0,r=0;
char check='y';
while(check!='n')
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
getchar();
printf("enter a number");
scanf("%d",&num);
if(num>0)
p++;
else if(num<0)
q++;
else
r++;
}
printf("positive=%d\t negative=%d\t zero=%d\t",p,q,r);
}
while(check!='n')
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
getchar();
printf("enter a number");
scanf("%d",&num);
The scanf("%d", &num); leaves the newline in the input buffer, thus in the next iteration of the loop, that is stored in check. After that, the getchar() consumes the 'n' or 'y' you entered. Then the scanf("%d", &num); skips the newline left in the buffer, scans the entered number, and leaves the newline in the buffer. You need to remove the newline between scanning in the number and querying whether you want a next iteration.
Above that, it would be better to exit the loop immediately after the user entered an 'n', so
while(check!='n')
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
if (check == 'n') {
break;
}
printf("enter a number");
scanf("%d",&num);
getchar(); // consume newline
would be better. That would still be open to bad things should the user input not match expectations, so if you want a robust programme, you need to check the return value of scanf to know whether the conversion was successful, and completely empty the input buffer before and after scanning in the number.
The issue is that the loop isn't exiting until the while condition is re-evaluated at the top of the loop. I'd suggest reworking your loop to something like this.
// we've purposely changed this to an infinite loop because
// we hop out on condition later
while(1)
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
getchar();
// here's the code that will jump out of the loop early if the user
// entered 'n'
if('n' == check)
break;
// user didn't enter 'n'...they must want to enter a number
printf("enter a number");
scanf("%d",&num);
if(num>0)
p++;
else if(num<0)
q++;
else
r++;
}
You are not checking the character input. Here is what it should be:
printf("do you want to enter a number y or n");
scanf("%c",&check);
/* This is what you need to add */
if (check == 'y') {
getchar();
printf("enter a number");
scanf("%d",&num);
}