I'm trying to write a program that involves comparing chars as part of a menu system for a program that decodes resistor codes. At the end of the menu it asks if you want to decode another resistor, repeating the program if the user selects "yes".
This is the code I have so far:
//used for repeating input menu
int menu = 0;
char menuChoice = 0;
//rest of program goes here
printf("Do you want to decode another resistor? (y/n)");
scanf("%c", &menuChoice);
while(menuChoice != "y" && menuChoice != "Y" && menuChoice != "n" && menuChoice != "N")
{
if(menuChoice != "Y" && menuChoice != "y")
{
if(menuChoice == "N" || menuChoice == "n")
{
menu = 0;
}
else
{
printf("Invalid choice.");
}
}
}
When I try to compile with GCC, I end up with a warning that says "comparison between pointer and integer." Since scanf only accepts a pointer, I don't know how exactly to compare the scanned char with to "Y" or "n". Is there something I'm missing here?
You are using the string literal syntax "a" instead of the char literal syntax 'a'
More about the difference
Adjust your comparisons. Presently they compare a an integer (or char such as menuChoice) to an array (such as "y").
// menuChoice != "y"
menuChoice != 'y'
The while(menuChoice != "y") && ...) likely should be removed.
The if(menuChoice == "N" ... should be else if(menuChoice == "N" ...).
Related
I'm trying to add a while loop inside the program. After it executes it's supposed to ask you if you want to continue and type in "y" if you do and "n" if you don't. If they do it's supposed to start over again, if not then it stops.
The thing is I wanted to make a message pop up if someone types in something other then "y" or "n" to require them to do that. The problem is the while loop will go on whatever they write in.
char cnd[100];
while(cnd[0] != 'n') {
printf("Program executing\n");
printf("Would you like to launch the program again? If not then type in 'n', if you do then type in 'y': ");
scanf("%s", &cnd);
while(cnd[0] != 'n' || cnd[0] != 'y') {
printf("You have to type in either 'y' or 'n':");
scanf("%s", &cnd);
}
}
return 0;
I tried to even test this by printing the user input before and after the statement. It does seem to be correct, so I don't know why the while loop won't work.
Let's translate your loop condition to plain English:
cnd[0] != 'n' || cnd[0] != 'y'
Basically, you're saying:
If the first character in cnd is something other than n, or the first character in cnd is something other than y, enter the loop.
This is unfalsifiable since cnd[0] will always be either not n or not y - it can't be both at the same time.
You should instead be asking:
If the first character in cnd is something other than n, and the first character in cnd is something other than y, enter the loop.
your while loop checks if it isn't y or isn't n one of those is always true try this instead
while(cnd[0] != 'n' && cnd[0] != 'y') {
The condition cnd[0] != 'n' || cnd[0] != 'y' is always true. You meant to use && (logical and).
You also need to drop & from &cnd (in both scanf calls) as that'd result in format specifier mismatch.
Also in the very first iteration cnd is uninitialized. You're better off using a do ..while loop or start cnd with "y" such as: char cnd[100] = "y";
Note the problems with scanf too.
read what you wrote (as code, not as english)
while(cnd[0] != 'n' || cnd[0] != 'y') {
if cnd[0] = 'n' then it doesnt = 'y' and vice versa.
you mean
while(cnd[0] != 'n' && cnd[0] != 'y') {
ie give the error is its not n and its not y
First and foremost: Why do you read a string when you want a single character? Use getchar(). Then check if there is other garbage after that character in the stream and act accordingly: Error message, clearing stdin:
#include <stdbool.h>
#include <ctype.h>
#include <stdio.h>
void clear(FILE *stream)
{
int ch;
// eat everything until a newline or EOF is encountered:
while ((ch = fgetc(stream)) != EOF && ch != '\n');
}
bool only_whitespace(FILE *stream)
{
int ch;
// eat all whitespace until a newline or EOF is encountered:
while ((ch = fgetc(stream)) != EOF && isspace((char unsigned)ch) && ch != '\n');
// ^^^^^^^^^^^^^^ don't pass signed values
// to the functions from <ctype.h>
if (ch == '\n') { // when the last character read was a newline
ungetc(ch, stream); // put it back into the stream
return true; // and tell the caller that all we encountered
} // was whitespace
return false;
}
int main(void)
{
int again;
do {
puts("Program executing\n");
while (printf("Would you like to launch the program again? If not then type in 'n', if you do then type in 'y': "),
(again = getchar()) != EOF && again != 'y' && again != 'n' || !only_whitespace(stdin))
{
fputs("Input error!\n\n", stderr);
if (again != '\n') // when the character read was not a newline
clear(stdin); // there could be other garbage left in the stream
}
clear(stdin);
} while (again == 'y');
// return 0; // Since C99 (i think) the effect of execution reching the end of main() without
// encountering a return-statement is the same as return 0; (same in C++)
}
So, I'm a C and programming newcomer and I'm trying to write a function to abstract y/n choices in a program that uses a lot of them, as of now I have it like this:
void chooser (char *choice)
{
while (1)
{
*choice='\0';
*choice=getchar();
while(getchar()!='\n');
if(*choice == 'y' || *choice == 'n')
break;
}
}
The second getchar consumes input in excess in the stdin so that it shouldn't be susceptible to the user typing gibberish.
The only problem is that if I type "ywhatever" or "nwhatever" the first getchar still captures "y" and "n" and passes it to the main.
I would like to have it so that the user has to type "y" or "n" and nothing else.
I could try ditching getchar and switching to fgets for capturing and sscanf for parsing, which is how I prefer to get strings, but, dunno, it's just a single character, I would prefer not to overcomplicate things.
Is there a way to scan stdin after user input to see if it contains more than one alphabetic character?
EDIT:
In the end, I went for this:
int chooser ()
{
char buffer[MAXIN];
while (1)
{
printf("y/n: ");
if (fgets(buffer, sizeof(buffer), stdin)!=NULL)
{
if (buffer[0] == 'y' || buffer[0] == 'n')
{
if (buffer[1]=='\n')
{
break;
}
else
{
while(getchar()!='\n');
}
}
}
}
if (buffer[0]=='y')
{
return 1;
}
if (buffer[0]=='n')
{
return 0;
}
}
It seems to be doing exactly what I need it to do, is there something else I should adjust? Does a fgets from the standard input need a if(fgets(...)!=NULL) check?
What's wrong with this solution:
#include <stdio.h>
void chooser(char *choice)
{
char buffer[200];
while (1)
{
fgets(buffer, sizeof(buffer), stdin);
if (buffer[0] == 'y' || buffer[0] == 'n')
break;
}
*choice = buffer[0];
}
int main(int argc, char **argv)
{
while (1)
{
char yn;
chooser(&yn);
if (yn == 'y' || yn == 'n')
printf("User choice: %c\n", yn);
}
}
That's not exactly "overcomplicated"
There is still room for improvement, e.g the EOF condition is not handled at all here.
Example of execution:
abc
def
y
User choice: y
n
User choice: n
yes
User choice: y
no
User choice: n
noooo
User choice: n
void answerme();
int main() {
char *answer = malloc (MAX_NAME_SZ);
....
printf ("\nWould you like to begin? [Y/N]");
fgets (answer, MAX_NAME_SZ, stdin);
answerme();
if(*answer == 'y' || *answer == 'Y'){
getinfo();
printf("\nprogram starting now...");
}
else if(*answer == 'n' || *answer == 'N'){
printf("\nThank you, program will close now....");
return 0;
}
...
} //end of main
void answerme(){
char *answer = malloc (MAX_NAME_SZ);
while(*answer !='n' && *answer != 'N' && *answer != 'y' && *answer != 'Y'){
printf("\nPlease enter [Y], or [N]");
fgets (answer, MAX_NAME_SZ, stdin);
}
};
What the point of this while loop or the whole function is that for it to check if the user has answered the question with a y/n rather than another random key. I want this while loop to continue asking the user for a Y/N input until the user inputs it. However for some reason when this program is run, the first step asks you if you would like to begin the program, and if you do answer Y, it will for some reason tell you "please enter Y or N" even though you did enter the right answer, and then when you do enter for example "n" or even any other random letter it will still let you through. So it seems like it registers the input but for some reason it still asks runs the while loop instead of skipping to the if(answer == Y) or the if(answer ==N).
Does anyone know what could be the reason this is happening?
Also once the user says "Y" and begins the program there will be a message asking the user to input certain information and this information gets stored into a structure which I created (not shown in the code), however with this while loop, this somehow gets skipped. If I take off this while loop, the whole program works fine, but of course the user will be able to skip through steps of the program without strictly inputing what I've asked of him.
If there's any better alternative way of restricting the user into only inputing what I've asked, please do enlighten me on that as this has been causing me issues and headaches for the past 3 days. Thank you !
The problem is that you set a variable *answer in the function and there is another one in the main program. However, it looks like they are expected to be the same variable.
To fix this, declare only one and share it between the two functions. Do that by declaring it outside any function, or pass it from main to the subfunction. Note that it should be malloc() only once.
Example of the parameter passing technique is:
void answerme (char *answer)
{
while (*answer !='n' && *answer != 'N' &&
*answer != 'y' && *answer != 'Y')
{
printf ("\nPlease enter [Y], or [N]");
fgets (answer, MAX_NAME_SZ, stdin);
}
}
int main()
{
char *answer = malloc (MAX_NAME_SZ);
....
printf ("\nWould you like to begin? [Y/N]");
fgets (answer, MAX_NAME_SZ, stdin);
answerme(answer);
if (*answer == 'y' || *answer == 'Y')
{
getinfo();
printf("program starting now...\n");
}
else
if (*answer == 'n' || *answer == 'N')
{
printf("Thank you, program will close now.\n");
return 0;
}
...
} //end of main
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10
void answerme();
int main() {
char answer[SIZE]="0";
printf ("\nWould you like to begin? [Y/N]");
scanf(" %s",answer);
if((strcmp(answer,"y")==0) || (strcmp(answer,"Y")==0))
{
printf("Answer is y\n");
printf("\nprogram starting now...");
answerme();
}
else
{
printf("Wrong input..exiting\n");
exit(1);
}
return 0;
}
void answerme()
{
char answer[SIZE]="0";
do
{
printf("\nPlease enter [Y], or [N]");
scanf(" %s",answer);
printf("You entered %s\n",answer);
}while((strncmp(answer,"y",1)!=0) && (strncmp(answer,"Y",1)!=0) && (strncmp(answer,"n",1)!=0) && (strncmp(answer,"N",1)!=0));
}
I am trying to end a program by giving the user the option whether to loop back to the start or exit. I've pasted this portion of the program below; 'homenumber' is where it should loop back to and is defined at the start of the program.
#include <stdio.h>
int main(void)
{
char option[1];
/*Asks if user wants to exit program*/
printf("Do you want to close the program? [Y/N]: ");
scanf_s("%c",&option,1);
if (option == "N" || option == "n") {
goto homenumber;
}
else if (option == "Y" || option == "y") {
;
}
Thanks in advance.
edit: My problem is the program won't let me enter a value for 'option' - it just ends the program no matter what
You should make option a char instead of a character array:
#include <stdio.h>
int main(void)
{
...
homenumber:
...
char option;
/* Ask if user wants to exit program */
printf("Do you want to close the program? [Y/N]: ");
option = 'Y';
scanf_s("%c",&option);
if (option == 'N' || option == 'n') {
goto homenumber;
} else
if (option == 'Y' || option == 'y') {
;
}
Note that you should also check the return value of scanf_s. I am setting option before the call as a quick and dirty solution. Using getchar() instead of scanf_s would be simpler and less error prone.
I am not condoning the use of goto either, just pointing at the actual issue you have trouble with.
I want this code to:
IF unsaved packets is greater or = 1,
then
print "There are unsaved packets"
"Would you like to saved them?"
"Type Y for Yes or N for No"
Get user input
IF User input = Y then function save
ELSE IF User input = N then exit
ELSE Return to menue
here is my current code, the problem is it won't take the input at all and if it does it doesn't use it to determine what happens after.
if(unsavedPackets >= 1)
{
puts("There are currently unsaved packets in the memory");
puts("\nWould you like to save them?");
puts("\nType Y for Yes or N for No");
getch(saveChoice);
printf("%c", saveChoice);
if(saveChoice == "Y")
{
puts("Saving records");
save(recordCount, records);
exit(1);
}
else if(saveChoice == "N")
{
exit(1);
}
else
{
printf("Returning to main menu");
}
}
break;
One problem is that
saveChoice == "Y"
where you should write
saveChoice == 'Y'
Similarly for "N"
In the first case, you are comparing char with const char * where second is pointer, not a character.
Your break statement will always be executed no matter if condition is true or false.
You are doing
if(savechoice =="Y")
it should be
if(savechoice == 'Y')
and likewise for 'N', since you are using char variable for storing user inputs.
There is problem with your if statement and also else if statement.
if(saveChoice == "Y")
and
else if(saveChoice == "N")
You are comparing a char with a string. You have to compare with char with a char like this
if(saveChoice == 'Y') and else if(saveChoice == 'N')
Always remember single quote for single character!!!