How can I make a loop that can take user input every time it loops?
#include <stdio.h>
#define WORD "jumble"
#define JUMBLED "mleujb"
int main()
{
char string[6];
int i = 0;
printf("The jumbled word is ");
printf(JUMBLED);
printf("\nCan you guess the original: ");
while(i == 0)
{
scanf("%d", string);
if (string == "exit")
{
return;
}
if(string == WORD)
{
i++;
printf("Kudos! You've guessed the word!");
}
else
{
printf("English please, good sir. Guess again.\n");
}
}
}
What I had hoped for was that every time the program went through the loop, it would want a new input with the scanf function. However, that apparently does not work that way. Instead, the program takes the value of the first scanf and uses it over and over again. If it is the wrong word, it will have an infinite loop.
This program has more than a few bugs in it: for instance, it does not actually compare the input to the actual word yet. As that does not pertain to the question, it is not my immediate concern.
you are using scanf() wrongly instead of scanf("%d",string) use scanf("%s",string) as %d is used for decimal input and %s is used for string input
Pseudo code for helping you precisely is not great
Also can you define a bit better your question ? you don't really say what is going wrong
but here is my guess
your test is i ==0 which means as soon as your user inputs the right word your exiting your loop...
I would guess your looking for something like
exit_condition = 0;
while (exit_condition == 0)
{
read keyboard entry
if(condition to exit loop)
{
exit_condition = 1;
printf("correct")
}
else
{
printf("try again")
}
}
Concerning the tests I think you need to read up bit on input and tests
try this
http://www.arachnoid.com/cpptutor/student1.html
scanf is incorrect for getting input string. It should be scanf("%s", string) as pointed out by others
String comparison cannot be done by using == in 'C'. It will only compare the address of two strings which will fail. Use 'strncmp' function instead.
Related
When I enter a string in the code below, the program doesn't move on. It just allows me to keep typing and pressing enter with no effect. Why does this happen and how can I fix it.
#include <stdio.h>
main() {
char str[20];
int aaa = 0;
int exit;
printf("Enter anything: ");
scanf("%s", str);
while(aaa == 0) {
if(str[3] == 'a') {
aaa++; }
else {
scanf("%d", &exit);
if(exit == 3) {
aaa++; } } }
printf("%s\n", str);
}
Log:
Enter anything: 2/3/4444
Now
it
just
lets
me
keep
on
typing
Edit: I solved it and I’m a bit embarrassed at how simple it was. I know people have been trying to explain this to me but in my own words this is what was happening: as the condition to enter the while loop was being met the program would enter the while loop. However, unless the input entered for the scanf satisfied one of the conditions in the loop, the program had no way of leaving the loop and therefore, it would get stuck. Basically I was simply missing an else statement which solved this problem.
After a string whose fourth character is not an a, your program reads an integer. It will never attempt to read anything but an integer after that first read. So you must not enter anything but an integer after the first string.
If you want your program to handle a non-integer after the string, you need to add code to do that. You currently have none.
C beginner here. For the program below, whenever the user inputs a character or a string it enters an infinite loop. How would you fix this while still using scanf? And what would be the better methods of writing this program rather than using scanf? Thanks to those who will answer.
#include <stdio.h>
#include <ctype.h>
int main() {
int rounds = 5;
do {
printf("Preferred number of rounds per game. ENTER NUMBERS ONLY: ");
scanf("%d", &rounds);
} while(isdigit(rounds) == 0);
return 0;
}
Using 'scanf' require the input to be formatted. Scanf has very limited ability to handle bad input. The common solution will be to use fgets/sscanf, following the structure below:
char buff[256] ;
int rounds = 0 ;
while ( fgets(buff, sizeof(buff), stdin) ) {
if ( sscanf(buff, "%d", &rounds) == 1 ) {
// additional verification here
break ;
} ;
} ;
// Use rounds here ...
The fgets/sscanf will allow recovery from parsing error - the bad input line will be ignored. Depending on requirement, this might be accepted solution.
I'd say there are just two "fixes".
Retain the scanf call(s), warts and all. Carefully refrain from typing non-digits when scanf is expecting digits.
Abandon scanf and use something else. We've just been discussing this tactic over at this new question.
Once you're using scanf, it's always tempting to try to "fix" it, so there's potentially a third answer lurking here, explaining how to do better, more user-friendly, more error-tolerant input while still using scanf. In my opinion, however, this is a fool's errand, a waste of time. The easy, obvious fixes for scanf's many deficiencies are themselves imperfect and have further deficiencies. You will probably spend more time trying to fix a scanf-using program than you would have spent rewriting it to not use scanf -- and you'll get overall better results (not to mention a cleaner program) with the non-scanf-using rewrite anyway.
Change
scanf("%d", &rounds);
To
int ret;
if ((ret = scanf(" %d", &rounds)) != 1) { // Skip over white space as well
if (ret == EOF) break;
scanf("%*[^\n\r]"); // Consume the rest of the line
}
If you really like scanf, you can use getch to discard non-numeric input:
int rounds = MIN_INT;
while (scanf("%d", &rounds)) != 1)
if (getc() == EOF) /* discard a rubbish character */
break; // or other error-handling return
// rounds is only valid if we did not break, when its value should be MIN_INT.
// but you might need another indicator
C beginner here as well. Like you, I use scanf, and it can be problematic sometimes.
I've had your same problem and tried to solve it with scanf and basic stuff before finding a better solution.
I've tried different solution from here but I continue to have the same problems again and again, like if I type:
a number followed by a character (e.g. 123a), the result is a valid number (which i don't want); the result is '123'.
a string of numbers and chars that begin with a number (e.g. 1a2b3), the result is still a valid number which is '1'.
a char at the beginning (e.g. a123) can generate infinite loop.
... and so on... I've tried do...while, only while, for... nothing.
The only solution I have found to prompt the user until he/she writes only numbers is the following, but...
NOTE: if the user type a space, the program considers only the part before it, e.g. '12 3', only 12 is considered, 3 doesn't exist... unless you want use an infinite loop like I did so, in this case, you can enter multiple numbers, check them and run your program on them all at once. e.g.: '12 23 34 45' ...
NOTE 2: this is a very basic beginner solution, I am learning, and this is just what I found with what I know. Can't do any better right now and, as I said, I didn't find any other solution that I liked the output.
NOTE 3: I use the counter to sum up all the inputs that are not numbers and store the value if it finds one. If I don't use this solution I'll end up in the case where if the first character is a number but the rest aren't, it's still valid (e.g.: '12w3' is 12, which I don't want)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main (void)
{
while (1) // try also multiple inputs separated by space
{
char str[10]; // should be enough for short strings/numbers (?!)
int strlength, num, counter;
do
{
printf("Enter a number: ");
scanf("%s", str);
strlength = strlen(str);
counter = 0;
for (int i = 0; i < strlength; i++)
{
if (!isdigit(str[i]))
counter++;
}
if (counter != 0)
printf("%s is not a number.\n", str);
} while (counter != 0);
num = atoi(str);
printf("%d is a number. Well done!\n\n", num);
}
}
You can also put it in a function and away from the main().
I'm creating a loop that basically has a (y/n) yes, no answer and I wanted to use an if else inside of a do while loop. When using the input == Y it seems to not accept it, so I'm wondering that's even possible in C? Or if I'm approaching in the wrong way.
I tried just a simple if input == Y but that didn't work, then I tried a strcmp and that didn't seem to work either. I'm at the strcmp part because I think I might be close to the answer with that but I'm not entirely sure if I'm understanding what's going on with the char values.
printf("Would you like to print another invoice? Y=yes, N=No\n");
do {
scanf("%s", &newInvoice);
if(strcmp(newInvoice, Y)!= 0) {
main();
}
else if(strcmp(newInvoice, N)!= 0) {
printf("Goodbye!\n");
}
else {
printf("Invalid Entry (it has to be y or n):\n");
}
} while(strcmp(newInvoice, N)!= 0);
When I had just input == Y it wanted me to initialize Ym and N so that didn't seem to be the answer. I would like the loop to repeat the question and input until they say yes or no; if they enter something like G or whatever other character it needs to loop again.
consider the following (changed abelenky's code a little). The below makes sure the lower case letters get accepted, but it's probably a little clunky, and may be represented a little more elegant.
int main()
{
char newInvoice, buffer;
do
{
newInvoice = getchar();
bufferClean(&buffer); //see underneath the code for the explanation.
if (newInvoice == 'Y' || newInvoice == 'y')
{
printf("you've chosen YES, continue ......\n");
break; // breaks the loop and continues with the code.
}
else if (newInvoice == 'N' || newInvoice == 'n')
{
printf("you've chosen NO, Goodbye!\n");
return 1; //main returns 1 and ends the program
}
else
{
printf("Invalid Entry (it has to be y or n):\n");
}
} while(1);
printf("exited the loop\n");
return 0;
}
Also, asking for users' input is a little tricky. I suggest clearing the buffer after using it, as it passes on the newline char and may skip any further input prompt.
I have created a little function to do so:
void bufferClean(char *buff)
{
while ((*buff = getchar()) != '\n' && *buff != EOF);
}
Just declare a char buffer in main() with no value, and pass it on to the function every time you want to clear the buffer (I do every time after asking for users' input). I'm a novice, and if I'm making any mistakes please point them out!
I am writing a program that starts printing at 0.
It prints up to 15 and asks the user a y/n question.
if y that program prints next 15.
if n program stops.
The program I wrote does not work.
Help solving this.
int main()
{
int i=0,k=1;
char ans;
while(k=1)
{
i++;
printf("\n%d",i);
if(i%15==0)
{
printf("\nDo you want to continue?(y/n): ");
scanf("%c",ans);
ans = toupper(ans);
if(ans=='Y') {
continue;
}
else if(ans=='N') {
k=0;
}
}
}
}
----------------------------------EDIT-------------------------------------
changed the code as #Programmer400. Also 15-->3. Now my computer prints
1
2
3
Do you want to continue?(y/n): y
4
5
6
Do you want to continue?(y/n):
7
8
9
Do you want to continue?(y/n): y
First it prints till 3 and asks. After Y, it prints till 6 and asks and then without any input prints till 9 and asks. Note the missing y in the 2nd question.
I have provided a working C program below that performs the tasks you specified in your question.
I have taken an effort to stay true to the functions that you used in your original code sample and I have also taken care to only make additions (not remove code).
In the comments, I have explained lines of code that I have added that were not in your original code sample.
#include <stdio.h>
int main(void)
{
int i = 0, k = 1;
char user_input;
char ans;
while(k == 1)
{
i++;
printf("%d\n", i);
if (i % 15 == 0)
{
printf("Do you want to continue? (y/n/Y/N): ");
scanf(" %c",&user_input); // Keep the whitespace in front of the %c format specifier -- it's important!
getchar(); // Consume the newline character left in the buffer by scanf()
// Check if user input is already capitalized
if (user_input >= 65 && user_input <= 90)
// If it is, keep it capitalized
ans = user_input;
else
// If it isn't, capitalize it
ans = toupper(user_input);
if (ans=='Y')
{
// Allow the loop to continue
continue;
}
else if (ans == 'N')
{
// Inform the user that execution is ending
printf("Exiting loop... ending program.\n");
// Consider removing 'k' entirely, just use a 'break' statement
k = 0;
}
else
{
// Inform the user that the input was not recognized (if not y/n/Y/N...)
printf("User input not recognized... please provide input again.\n");
// Decrement 'i' so that the user is forced to provide input again...
i--;
// Allow the loop to continue
continue;
}
}
}
}
Helpful notes:
scanf leaves a newline character in the buffer when you are reading user input with character formatters. Namely...
%c, %n, and %[] are the 3 specified expectations that do not consume leading whitespace
-- From a comment on this StackOverflow answer.
Keep in mind that if you would like to exit your while loop, you could simply insert a break statement. This way, you don't have to change the value of k (which is rather ambiguous) to end the loop and the code is more readable because an explicit break statement is harder to misinterpret. In this simple case, the use of k is easily understood (so don't worry about it too much, for now).
If you ever intend to read string input from a user (i.e., an array of characters), then I would recommend that you use fgets() instead of scanf(). A discussion of the merits of fgets() in comparison to scanf() is provided in this StackOverflow answer. Further, it is important to recognize that even though you can use gets() to perform a similar operation it is highly dangerous and never advised. Check out the explanations provided by the top two answers to this StackOverflow question.
I tried changing your code so that it doesn't generate warnings, now it seems to "work" (but maybe it can be even more correct).
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
int main()
{
int i=0,k=1;;
char c;
char ans[] = "";
while(k==1)
{
i++;
printf("\n%d",i);
if(i%15==0)
{
printf("\nDo you want to continue?(y/n): ");
scanf(" %c",ans);
ans[0] = (char) toupper(ans[0]);
if(ans[0]=='Y') {
continue;
}
else if(ans[0]=='N') {
k=0;
}
}
}
}
I have a some code, and the function I am having trouble with is this:
unsigned int getInputData() {
printf("Please input a positive integer number terminated with a carriage return.\n");
do{
scanf("%c", &input);
if(isdigit(input)) {
temp = charToInt(input);
rValue = mergeInt(rValue, temp);
}
if(rValue >= imax) {
rValue = 0;
printf("ERROR: That is too large of an integer. Please try again. \n");
}
else if(isalpha(input)){
rValue = 0;
printf("This is not a integer. Please try again. \n");
}
else{
printf("OK. This is a good number. \n");
}
} while(1);
}
I'm scanning in each char individually, merging it into an int. Which is exactly what I want to do BUT I only want it to print "OK. This is a good number." once when the user types it in. Example: If someone was to type in: 12345 I want it to return: "OK. This is a good number." once for those 5 char rather than once each. Hoping this makes sense, been at it for awhile so anything will help.
There's huge logic problems behind your code:
You loop infinitely without checking for end of input:
You say you want to tell whether this is a good number when the user inputs several digits, but you do only read one character at a time, and you do not define how a number ends.
Though you do specify to end with a carriage return, you did not design your algorithm that way, you never check for the \n character.
You define a return value for the getInputData() function but you do never return from that function.
You test whether input is a digit to update the value, but for errors you do show an error only if it's an alphabetic character.
Basically, to keep with the way you wrote your algorithm, here's another take:
unsigned int getInputData() {
char input;
long value=0;
do {
scanf("%c", &input);
if (isdigit(input))
value = value*10+input+'0';
else if (input == '\n')
return 1;
else
return 0;
} while(1);
}
int main() {
printf("Please input a positive integer number terminated with a carriage return.\n");
if (getInputData() == 1)
printf("OK. This is a good number.\n");
else
printf("This is not a integer. Please try again. \n");
return 0;
}
but I do exit from the infinite loop to be able to check the result.
N.B.: for the purpose of the example, I did not check for overflows.
N.B.1: I kept using scanf() to stay close to your code, but if you only want to read one character at a time, it is better to use getchar() which is way simpler and faster.
N.B.2: you can also simplify your code by using more features of scanf():
unsigned int getInputData() {
unsigned input;
long value=0;
int n;
do {
n = scanf("%u", &input);
if (n == 0)
return 0;
else
return 1;
} while(1);
}
You may even try to use scanf("%a[0-9]") which is a GNU extension. See man scanf for more details.