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?`.
Related
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.
I am working on an assignment in C, trying to create a program that simulates a "Rock, Paper, Scissors" match between the user and the computer. Everything is working fine except the for loop I have created is skipping the first iteration of the loop and going straight to my second match. Is there any way to fix this? Code and compilation below
main.c
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int main(void) {
srand(time(0)); // This gives the random function a new seedallows me to use time in order to create "random" numbers. //
time_t t; // Allows the program to store system time values. //
int R; // This statement declares the variable for the move "Rock". //
int P; // This statement declares the variable for the move "Paper". //
int S; // This statement declares the variable for the move "Scissors". //
int numMatches; // This statement declares the variable for the number of matches that are to be played. //
int roundNumber; // This statement declares the variable for the current round of the match that is being played. //
int compMove; // This statement declares the variable that represents the move (rock, paper, or scissors) that the computer makes. //
char userMove; // This statement declares the variable that represents the move (rock, paper, or scissors) that the user of the program chooses. //
int randNumber; // This statement declares the variable for the random number that will be generated. //
printf("Starting the Rock, Paper, Scissors Game!\n");
printf("Enter the number of matches to play: ");
scanf(" %d", &numMatches); // This statement allows the user to input the number of matches he/she wishes to play. //
for (roundNumber = 1; roundNumber <= numMatches; roundNumber++) { // This for statement first initializes the number of rounds to 1. Then, the statement sets a parameter that the for loop will only continue as long as the number of matches completed is less that than the total matches that are to played. The last statement increments
printf("\nMatch %d: Enter R for rock, P for paper, or S for scissors: ", roundNumber);
fflush(stdin);
userMove = getchar();
randNumber = (rand() % 3) + 1; //1 to 3//
compMove = randNumber == 0 ? 'R' : randNumber == 1 ? 'P' : 'S';
if ((userMove == 'R') && (compMove == 'S')) { // These statements state the result of the game depending on the user's move and the computer's move. //
printf("The computer chose scissors. You won \n");
} else
if ((userMove == 'P') && (compMove == 'R')) {
printf("The computer chose rock. You won \n");
} else
if ((userMove == 'S') && (compMove == 'P')) {
printf("The computer chose paper. You won \n");
} else
if ((userMove == 'R') && (compMove == 'R')) {
printf("The computer chose rock. You tied \n");
} else
if ((userMove == 'P') && (compMove == 'P')) {
printf("The computer chose paper. You tied \n");
} else
if ((userMove == 'S') && (compMove == 'S')) {
printf("The computer chose scissors. You tied \n");
} else
if ((userMove == 'R') && (compMove == 'P')) {
printf("The computer chose paper. You lose \n");
} else
if ((userMove == 'P') && (compMove == 'S')) {
printf("The computer chose scissors. You lose \n");
} else
if ((userMove == 'S') && (compMove == 'R')) {
printf("The computer chose rock. You lose \n");
}
}
return 0;
}
compile
The line:
userMove = getchar();
Catches the char but lets a newline character \n in the buffer caused by pressing Enter, you need to discard it.
You can do, for instance, this:
userMove = getchar();
getchar(); // <-- catches and discards '\n'
I would also get rid of fflush(stdin), it causes undefined behaviour, reasons in Why should I use fflush(stdin) in this program?.
Replace it also with getchar(). Or use type specifier with discard in your scanf function like scanf(" %d%*c", &numMatches);
Here is a working sample
Another thing that is not very good is the fact that none these variables is being used:
time_t t; // Allows the program to store system time values. //
int R; // This statement declares the variable for the move "Rock". //
int P; // This statement declares the variable for the move "Paper". //
int S; // This statement declares the variable for the move "Scissors". //
I'm facing a problem with what I enter with any unknown during the first time to the program. it will show me an infinite loop problem program closing. The program won't read the else statement.
char cont;
printf("Do u want continue\n");
scanf("%c", &cont);
getchar();
do
{
if (cont == 'y' || cont == 'Y')
{
selection();
}
else if (cont != 'n' || cont != 'N')
{
printf("Program Closing \n");
}
else
{
printf("Invalid Please Re-enter");
getchar();
scanf("%c", &cont);
}
} while (cont != 'n'&& cont != 'N');
let's dissect your code line by line starting with
scanf("%c", &cont);
This line would get a char value from stdin and put it into cont, which is a char so that's fine
getchar();
All I have to say for this is, why? it doesn't do anything useful, remove it.
Entering the loop now we have this statement
if (cont == 'y' || cont == 'Y')
this line is correct, it checks if the character is equal to y or Y
else if (cont != 'n' || cont != 'N')
this line is the main issue, your statement checks if cont is a value NOT equal to n or N, i.e. as a comment mentioned above, if the user put in the value a this line would return true, and then end the program. To correctly check if the user wants to exist you can use the same if statement used for y
if (cont == 'n' || cont == 'N')
if you replace the original if statement with this your program should work as expected. Just remember in the future that the != means not equal to, i.e. if the value is anything besides n or N return true. The == operator checks for equality as you saw above, so the line cont == 'n' means return true if cont is the same value as 'n'
printf("Invalid Please Re-enter");
getchar();
scanf("%c", &cont);
also as an extra note, please explain why you keep throwing in useless getchar()'s, those lines literally do nothing and you should remove them.
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.
I've looked at questions asked on stackoverflow before, but this is my first time asking, so I apologize in advance for any format mistakes. I've been taking a class on C programming for about a month, and I've been given an assignment to use a do/while loop in my main function to loop a displayMenu(), which allows the user to input either 1, 2, or 3 to display a certain block of information.
int main(void)
{
int option = 0;
do
{
option = displayMenu();
}
while (option == displayName() || displayColor() || displayFood());
}
//Display the menu for choosing an option or exiting the program
int displayMenu()
{
int choice = 1;
while (choice == 1 || 2 || 3)
{
puts("Choose which piece of information you would like to know:");
printf("%s", "1 - My name, 2 - My favorite color, 3 - My favorite food\n");
printf("%s", "Or type in any other number to exit the program: ");
scanf("%d", &choice);
puts("");
if (choice == 1)
displayName();
if (choice == 2)
displayColor();
if (choice == 3)
displayFood();
}
return choice;
}
Now, I'm sure the error is somewhere within these two methods, but just in case, I'm posting the display methods.
//Function to display my name
int displayName()
{
int value = 1;
puts("My name is x.\n");
return value;
}
//Function to display my favorite color
int displayColor()
{
int value = 2;
puts("My favorite color is y.\n");
return value;
}
//Function to display my favorite food
int displayFood()
{
int value = 3;
puts("My favorite food is z.\n");
return value;
}
If the user inputs 1, 2, or 3, the program correctly displays the information and loops to prompt the user again about inputting another value. However, if any other number is input, the program prompts the user again to input a value, when instead it should be closing the program.
What am I doing wrong? I tried inserting a
else return choice;
after the first three if statements, because i thought that would be needed to break the loop, but it didn't work. Does it have something to do with my while conditions? I'm unsure if my conditions are right, (about == and || precedence and whatnot), so if someone could clarify that too it'd be nice.
I know there are probably more efficient methods to executing this program, but I'm limited to what I've been taught in the class, which really isn't anything more than what I've coded.
while (choice == 1 || 2 || 3)
is equivalent to
while ((choice == 1) || 2 || 3)
which is equivalent to
while (1)
What you want is:
while (choice == 1 || choice == 2 || choice == 3)
This line is an infite loop:
while (choice == 1 || 2 || 3)
I guess what you want is:
while (choice == 1 || choice == 2 || choice == 3)
Ignoring the many errors in the original code, what you can do to refactor the loop logic is to use an array of function pointers:
int (*functions[])(void) = { displayName, displayColor, displayFood };
int choice = -1;
do {
choice = get_choice(); // assuming get_choice returns an integer between 0 and 2, or -1 on error/eof.
if (choice != -1)
functions[choice]();
} while (choice != -1)
this will make your code more concise, provided all of your functions have the same prototype.
Well because you got your answer I will not try to give you another Answer which will probably be the same.
One thing you should know, what happens if the user type a letter or a number + a letter (1j) ?
You should have control of your programs when you are dealing with text menus.
Here is a better approach of your program:
#include <stdio.h>
#include <string.h>
int checkInput(int min, int max){
int option,check;
char c;
do{
printf("Choose an Option:\t");
if(scanf("%d%c",&option,&c) == 0 || c != '\n'){
while((check = getchar()) != 0 && check != '\n');
printf("\tThe option has to be between %d and %d\n\n",min,max);
}else if(option < min || option > max){
printf("\tThe option has to be between %d and %d\n\n",min,max);
}else{
break;
}
}while(1);
return option;
}
void quit(void){
printf("Goodbye...\n");
}
//Function to display my name
int displayName(void){
int value = 1;
puts("My name is x.\n");
return value;
}
//Function to display my favorite color
int displayColor(void){
int value = 2;
puts("My favorite color is y.\n");
return value;
}
//Function to display my favorite food
int displayFood(void){
int value = 3;
puts("My favorite food is z.\n");
return value;
}
int displayMenu(void);
int main(void){
int option = 0;
do{
option = displayMenu();
}
while (option != 0);
}
//Display the menu for choosing an option or exiting the program
int displayMenu(void){
int choice;
do{
puts("Choose which piece of information you would like to know:");
printf("%s", "1 - My name\n2 - My favorite color\n3 - My favorite food\n\n");
printf("%s", "Or type in any other number to exit the program: ");
choice = checkInput(0,3);
puts("");
if (choice == 1){
displayName();
}else if (choice == 2){
displayColor();
}else if (choice == 3){
displayFood();
}else if( choice == 0){
quit();
}
}while (choice != 0);
return choice;
}
probably a do{}while(); is better then while{}.