Having trouble with C program output - c

As far as I know regardless of any other issues the program below should print out the title and menu options, and then prompt for user input.
However, it does absolutely nothing and when I stop the execution it prints out the menu etc and then, as it hasn't asked for the user inputted option it repeatedly prints the "This is not a valid option" line.
*EDIT: I have completely removed the loops. All I have in the program is print the title, print the menu, ask for user input, and I still get nothing to the console until after I terminate. Is there something wrong with my asking for input?
EDIT2: It's definitely the scanf as without it everything works. I ran the code with an added function to print out the value stored in option and it told me -1 when I hadn't previously set it to 0 before asking the user to input. The program seems to be automatically assigning option instead of bothering to ask the user what they want.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main ()
{
/*Print Title*/
printf("Maths Quiz Game \n");
printf("\n");
int i;
int rightCount = 0; //count of right answers
int wrongCount = 0; //count of wrong answers
int questions = 0; //user input for number of questions
int exit = 0; //store exit option
int option = 0; //menu option
while(exit == 0) //while loop that keeps program running until exit is chosen
{
/*Menu Options*/
printf("Please choose an option from the menu below. Enter the number of your choice. \n");
printf(" 1. Choose number of questions for this round. (Max = 5) \n");
printf(" 2. Start Quiz \n");
printf(" 3. Display total of right and wrong answers. (Only availanle after quiz) \n");
printf(" 4. Exit Game \n");
scanf("%d", &option); //taking user menu option
/*Error check for any input that is not a valid option. It continues until valid entry*/
while((option != 1) || (option != 2) || (option != 3) || (option != 4))
{
printf("\n That is not a valid option. Please try again. \n");
scanf("%d", &option);
}

while((option != 1) || (option != 2) || (option != 3) || (option != 4))
what ever option value you enters assume 1, 1st condition of while() will be false but remaining are true so enters into loop and prints "That is not a valid option. Please try again." so replace || with logical And(&&).
while((option != 1) && (option != 2) && (option != 3) && (option != 4))
now here if you entered correct input it will not display "That is not a valid option. Please try again"

How about changing
while((option != 1) || (option != 2) || (option != 3) || (option != 4))
{
printf("\n That is not a valid option. Please try again. \n");
scanf("%d", &option);
}
to something else like
if ((option != 1) || (option != 2) || (option != 3) || (option != 4))
{
printf("\n That is not a valid option. Please try again. \n");
// scanf("%d", &option); // This is probably not required
}
or
if ( option >= 1 && option <= 4)
{
printf("\n That is not a valid option. Please try again. \n");
// scanf("%d", &option);
}
Because you are using infinite loop outside, why would you need one inside? All you need is to check the option and show the menu if an unavailable option is selected.
All of your logic you can put in this if afterward, one for each option selected.
Better use switch for good understanding
/* After selecting an option */
switch (option)
{
case 1:
/* Do the operation according */
break;
case 2:
/* Do the operation according */
break;
case 3:
/* Do the operation according */
break;
case 4:
/* Do the operation according */
break;
default:
/* If none of the option selected */
printf ("Wrong input! \n")
break;
}
Hope you got it.

The problem was with the printf function in that it didn’t print out until after you had entered the following options, it didn’t ask until after the user had answered. A simple flush after the printf sorted this out.

Related

Stop a user introducing values for an array

I have a program to introduce temperatures, and I need to ask what scale he wants to insert the data, and then receive a list of temperatures. Then I need to convert that list.
But what would I put for a stop condition in the while since 0 can be a temperature?
int main(int argc, char const *argv[]) {
int n = 0;
int temperaturas[TAMANHO];
char escala;
printf("Escala: ");
scanf("%c", &escala);
puts("Para PARAR Prima 0");
while (temperaturas[n - 1] != 0) {
if (escala == 'C') {
printf("\n\tCelcius: ");
scanf("%d", &temperaturas[n]);
} else
if (escala == 'K') {
printf("\n\tKelvin: ");
scanf("%d", &temperaturas[n]);
}
n++;
}
escreverTemperaturas(temperaturas, escala, n);
return 0;
}
From what i understood from your question , you want to the user to stop typing the temperatures whenever he wants , or when the the list is full .
Basiclly , you can simply switch your program a bit by asking the user if he wants to continue typing , otherwise when n > TAMANHO .
while ((n<= TAMANHO) || (continue != N))
{
if (escala == 'C')
{
printf("\n\tCelcius: ");
scanf("%d", &temperaturas[n]);
}
else if (escala == 'K')
{
printf("\n\tKelvin: ");
scanf("%d", &temperaturas[n]);
}
printf("Would you like continue typing the temparutres ? ");
scanf(" %c",&continue);
n++;
}
Tips :
You should control the inputs as if he doesn't type C or K it should be another condition as printing a message to inform ( same for &continue);
also i advice you to read this previousely asked question about how
scanf("%c", &escala);
should be replaced with
scanf(" %c", &escala);
Read this, about scanf:
"On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file." http://www.cplusplus.com/reference/cstdio/scanf/
So you can just use the value returned by scanf.
do {
printf("Escala: ");
scanf(" %c", &escala);
} while( escala != 'C' && escala != 'K');
do {
escala == 'C' ? printf("\n\tCelcius: ") : printf("\n\tKelvin: ");
} while( n < TAMANHO && scanf("%d", &temperaturas[n++]) == 1 );
When there's nothing left to read (or the input is not a number) scanf returns 0 breaking the loop.

Scanf in visual studio not accepting multiple cases of characters

I'm creating a conversion project for letters/numbers ASCII table. My code is supposed to be 'interactive', so the user would type 'y' or 'n' to answer questions on the screen. However, it doesn't want to do this twice...
I have tried:
Just trying numbers instead of characters, but it's not exactly what I want
The %[\n]*c, and %[\n]c, and %[\n]*s ... technique but it doesn't help ;-;
Testing in a different project, but the only way I am able to do it is for multiple scanf()s to be in a row.
Here is the code:
printf("Would you like to convert a number today? \n");
printf("Please press Y or N \n");
scanf("%c", &input);
if (input == 'y' || input == 'Y') { //compare input if they said 'yes'
printf("\nThank you! \nWhat number?\n");
scanf("%d", &number);
flag = test(number);
if (flag == 0) { //if there is an equivalent letter
letter = conversion(number); //find the equivalent letter
printf("\nYour Number \t ASCII letter\n");
printf("%d\t %c\n", number, letter);
}
}
else if (input == 'n' || input == 'N') {
printf("\nWould you like to convert a letter instead? This time enter 0 or 1\!\n\n"); //problem here!!
printf("I wish I could say it was to \' Spice things up \' ...but it\'s not ;-; \n\n");
scanf("%d", &input2);
if (input2 == 0) { //this needs to be checking whether the user input Y/y
printf("Great choice adventurer!\n");
printf("What letter will it be today?\n\n");
//..I would go to a different funtion here ie: test2(letter)...
scanf("%d", &number); //I showed that it worked with multiple numbers, but I can't get this to work with multiple letters
printf("%d", number);
}
if (input2 == 1) { //this needs to be checking whether the user input N/n
printf("Difficult to please, I see...\n\n");
printf("I suggest you move on with that attitude!\n\n");
printf("Bye bye then\n");
}
}
else { //if they tried to break the code
printf("Sorry I did not recognise your command...please retry\n");
printf("Press Y or N next time!\n");
}
The first check works perfectly, I just want the second check to be like the first!
Some 'solutions' caused a overflow, which I don't want if possible
Even if someone could explain why this isn't working the way I intended would be very helpful!
I'm not sure what confuses you.
Use
char foo;
scanf(" %c", &foo);
for single characters, eg. letters and
int bar;
scanf("%d", &bar);
for numbers, integers. If you type a letter instead, scanf() will fail.
%[...] is for strings.
scanf() returns the number of successful conversions (or EOF), so for
int height;
int width;
scanf("%d %d", &height, &width);
it returns 2 if successful. It might return 1 if only height could be read.
So to check for errors on user input you should do:
int height;
int width;
if (scanf("%d %d", &height, &width) != 2) {
// handle the error, maybe exit the program.
}
Your code could look like that (without error handling):
#define _CRT_SECURE_NO_WARNINGS // you said Visual Studio? Without it you should get
// warnings about some functions being insecure.
#include <ctype.h> // isalpha() returns true if the value is a letter
#include <stdlib.h> // EXIT_SUCCESS
#include <stdio.h> // puts(), printf(), scanf()
int main(void)
{
for(;;) { // for-ever ... endless loop since the user exits by answering
// 'n' or 'N' two times
puts("Would you like to convert a number today?\nPlease press Y or N:");
char input;
if (scanf(" %c", &input) != 1) // We reached EOF ... end of file
break; // that's improbable for stdin,
// but input could be redirected to
// read from a file instead.
if (input == 'y' || input == 'Y') {
puts("\nThank you!\nWhat number?");
int number;
scanf("%d", &number);
if (isalpha((char unsigned)number)) // *)
printf("\nYour Number \t ASCII letter\n%d\t %c\n\n", number, number);
else
puts("Sorry, but that's not the ASCII code of a letter :(\n");
}
else if (input == 'n' || input == 'N') {
puts("\nWould you like to convert a letter instead?\nPlease press Y or N:");
scanf(" %c", &input);
if (input == 'y' || input == 'Y') {
puts("\nGreat choice adventurer!\nWhat letter will it be today?");
char letter;
scanf(" %c", &letter);
if (isalpha(letter))
printf("\nYour letter \t ASCII code\n%d\t %c\n\n", letter, letter);
else
puts("Sorry, but that's not a letter :(\n");
}
else if (input == 'n' || input == 'N') {
puts("\nDifficult to please, I see...\n\nI suggest you move on with that attitude!\n");
puts("Bye bye then.");
return EXIT_SUCCESS;
}
}
else {
puts("Sorry I did not recognize your command... Please retry.");
puts("Press Y or N next time!\n");
}
}
}
*) isalpha() (and the other functions in <ctype.h>) expects a value that fits in a unsigned char or the value EOF. It has undefined behaviour for other values. Since we read user input into an int we cannot be sure that's the case so we have to cast the value to unsigned char before passing it to isalpha() (and friends).
Next time you ask a question please include your full code, including variable declarations, functions like test() and conversion() and #includes. But please, post an example that focuses on your problem at hand. All that dialog you included would not have been necessary.

do while 1-4 menu loop continually repeating for non numerical input

I'm having trouble with this do while menu loop as part of a bigger programming question, it keeps repeating for any non numerical input. How can I prevent this ?
Any help would be great thanks!
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main (void)
{
int option = 0;
do
{
printf("--- Menu---\n1) Option 1\n2) Option 2\n3) Option 3\n4) Exit\nPlease select an option (1, 2, 3, or 4):");
if ((scanf("%d", &option) != 1))
{
printf(">Invalid option! ");
}
switch(option)
{
case 1: printf(" 1 \n");
break ;
case 2:printf(" 2 \n");
break ;
case 3: printf(" 3 \n");
break ;
case 4: printf(" The program has terminated\n");
break;
}
}while(option != 4);
return 0;
}
The reason it keeps repeating is because
scanf("%d", &option)
will return 0 when you enter a non-numerical input. scanf fails but it does
not clean the input buffer, that means that non-numerical input will remain in
the input buffer.
Because you don't exit the loop on error
if ((scanf("%d", &option) != 1))
{
printf(">Invalid option! ");
}
scanf will once again try to read from stdin. But because of the previous failure,
the input buffer will still have the last non-numerical input and scanf will fail
again, and so. Hence it keeps repeating.
You have to leave the loop on error:
if ((scanf("%d", &option) != 1))
{
printf(">Invalid option! ");
break;
}
which will end the program. But if you don't want the program to end but print
the menu and wait for user input, then you have to "clean" the input buffer. You
can use this function:
void clean_stdin(void)
{
int c;
while((c = getchar()) != '\n' && c != EOF);
}
and then
if ((scanf("%d", &option) != 1))
{
printf(">Invalid option! ");
clean_stdin();
continue; // to skip the rest of the loop
// and start the loop again
}

scanf and the char variable don't get a long [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 6 years ago.
#include <stdio.h>
#include <conio.h>
void main(){
int turn,i=1,num;
char answer;
for(i>0;i++;){
printf("Please enter a number in the range 1-5:");
scanf("%d",&num);
if (num == 1){
printf("Disconnecting\n");
continue;
}
else if(num == 2){
continue;
}
else if(num == 3){
printf("Are you sure you would like to finish your order??? \nplease enter one char:");
scanf("%c", &answer);
if(answer == 'y'){
printf("Canceled");
break;
}
else{
continue;
}
}
else if(num == 4){
turn=i-1;
printf("your position in queue is:%d\n",turn);
continue;
}
else if(num == 5){
break;
}
else {
printf("Wrong input\n");
continue;
}
}
getch();
}
I'm using c language for this,
if You look at the
else if(num == 3)
it should function in a way that when I enter the letter y,Y it will say canceled and end the program and if not it will just reset the loop.
now when I use the number 3 and give the variable c the letter 'y'
it just says nothing and acts like I gave it the command "continue" + pressed the number 3 again although all I have done is press y or Y and enter.
everything else is good.
I would be glad if anyone can tell me how to fix that.
for(i>0;i++;){
printf("Please enter a number in the range 1-5:");
scanf("%d",&num);getchar();
//... rest of your code
}
use getchar or getch to consume extra newline character
The getch found at the bottom of your main is being used to get order numbers.
Try putting a "getch" in right before you are looking for your y character.
That is to say, something like:
else if(num == 3){
printf("Are you sure you would like to finish your order??? \nplease enter one char:");
getch();
scanf("%c", &answer);
if((answer == 'y') || (answer == 'Y')) {
printf("Canceled");
exit;
} else {
continue;
}
}

C Booking Issues

typedef struct contact {
char firstname [40];
char lastname [40];
char address [100];
char phone[10];
}contact;
int main ()
{
FILE *pFile;
contact entry = {"", "", "", ""};
int choice;
char cont = 5;
pFile = fopen("C:\\contacts.txt", "w+");
if(!pFile){
printf("File could not be open");
return 1;
}
printf("Choose a selection\n\n");
printf("1. Enter First Name\n");
printf("2. Enter Last Name\n");
printf("3. Enter Address\n");
printf("4. Enter Phone Number\n\n");
scanf( "%d", &choice);
while (choice = 1|2|3|4|cont){
if (choice = 1){
printf ("First name: ");
fgets(entry.firstname, sizeof(entry.firstname),stdin);
}
else if(choice = 2){
printf ("Last name: ");
fgets(entry.lastname, sizeof(entry.lastname),stdin);
}
else if(choice = 3){
printf ("Address: ");
fgets(entry.address, sizeof(entry.address),stdin);
}
else if (choice = 4){
printf ("Phone number: ");
fgets(entry.phone, sizeof(entry.phone),stdin);
}
else
printf("Exiting");
break;
fwrite (&entry, sizeof (struct contact), 1, pFile);
printf ("Would you like to enter a new contact? (y/n)");
scanf ("%d", &cont);
if (cont = 'n'|'N')
return 0;
}
fclose(pFile);
getchar();
return 0;
}
is my code at the moment. Each time I give any option 1,2,3,4, put in a entry and press enter the window closes. I'm unsure if the logic makes sense and any suggestions are welcome but it "seems" okay to me but obviously I need another set of eyes. I want it where I don't have to enter all entries for every person I put in the file. Also, to note, I initially cont to 5 just because it was complaining.. bad practice I know. Any helpful information is appreciated
Your program ends because the break; isn't in the scope you think it is:
else if (choice = 4){
printf ("Phone number: ");
fgets(entry.phone, sizeof(entry.phone),stdin);
}
else
printf("Exiting");
break;
Even though you've indented the break, it doesn't belong to the else clause. So no matter what happens in the if/else block, the break gets executed and your program breaks out of the loop and ends.
To fix it, add braces to enclose the break inside the scope of the else.:
else if (choice = 4){
printf ("Phone number: ");
fgets(entry.phone, sizeof(entry.phone),stdin);
}
else
{
printf("Exiting");
break;
}
And once you fix that, this line will cause your program to terminate because it always evaluates to true and returns from main:
if (cont = 'n'|'N')
return 0;
You want that line to say
if (cont == 'n' || cont == 'N')
return 0;
These fixes will at least stop your program from terminating, but as others have pointed out there are numerous logical errors elsewhere that will prevent it from doing what you want.
For example, the following line:
while (choice = 1|2|3|4|cont){
belies a misunderstanding of some fundamental concepts.
First = is the assignment operator. The above code, among other things, changes the value of choice. Use == for equality comparison.
Second, the | operator is a bitwise or. The value of 1|2|3|4|5 is 7 (I'll leave it to you to figure out why sometime). Instead, use || like this:
while (choice == 1 || choice == 2 || choice == 3 || choice == 4 || choice == cont) {
There are other similar errors throughout your code.
A single = does assignment in C. if (a = 5) { /* always executed! */ } sets a to 5 and then executes the if-branch because a = 5 evaluates to 5 which is considered true.
You want == which compares values. Thus:
if (choice = 1){
Should be
if (choice == 1){
Another thing:
while (choice = 1|2|3|4|cont){
Does not do what you think it does. It's actually computing the bitwise or of 1, 2, 3, 4 and cont. (So just changing = to == wouldn't be sufficient.) You need to compare each value in turn:
while (choice == 1 || choice == 2 || choice == 3 || choice == 4 || choice == cont){
Also notice the use of || (logical OR) instead of bitwise or.
EDIT: The reason your program prematurely exits is because of the following:
else
printf("Exiting");
break;
You're missing curly braces ({ and }), so it actually means the following (despite misleading indention):
else
printf("Exiting");
break;
Your code probably has more errors.
By using if (choice = 1) you are saying "If I change choice to 1" which is virtually guaranteed to work, but it destroys the previous value choice held.
You want to start off with if (choice == 1) which means "If I compare choice to 2, is this equal?`.

Resources