I'm making a train scheduling program. In my If condition, I only want to accept 10 train ids between 100 and 200. My program is running on command prompt but my If condition is totally ignored. How should I fix this so that my program will accept ids between 100 and 200 and request the user to enter the train id again if it's not obeying the condition?
My Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int train_id;
int train_time;
} TrainDetails;
void enterID(TrainDetails array[10]);
int main()
{
TrainDetails array[10];
enterID(array);
return 0;
}
void enterID(TrainDetails array[10])
{
int count = 1;
int enter_Tid;
while(count < 11)
{
printf("Enter Train ID :\n");
scanf("%d",&enter_Tid);
if(enter_Tid>100 && enter_Tid<200)
{
array[count].train_id = enter_Tid;
}
count++;
}
}
you should implement a slightly different approach (it was posted on a different post. Not the same thing but a similar structure that you can use: how to use a while loop to keep asking for input until the input is correct (C)?).
These are basic control flow structures, so I suggest reading a good beginners book on the basics of programming.
int tid = -1;
while (true){
printf("input an integer value: ");
scanf("%d",&tid);
if (tid > 100 && tid < 200 ){
printf("successfully read an item");
break;
} else {
printf("Invalid tid. Retry.");
}
}
If you don't want to use the break statement you can use this kind of basic control flow:
do {
printf("input an integer value: ");
scanf("%d",&tid);
} while (tid < 100 || tid > 200);
These should be inside a bigger loop where you decide how many of these train IDs you need.
Your program does not produce any output besides the "Enter Train ID" prompts, so the only way I can imagine for you to have concluded that your if condition is being ignored is by counting the number of prompts emitted before the program terminates. Seeing only ten total even in the event that you enter an out-of-range train id, you assume that the if condition that you are using to validate the inputs has been ignored.
But that depends on an aspirational expectation of how your program will behave, not a reasonable expectation of the code you actually presented. Consider, what work is performed by the code inside the if statement's body? Only one thing: assigning the entered ID to a train. So if the user enters an invalid ID then that will not happen, but everything else in the loop body still will. In particular, count is incremented at the end of the loop regardless of whether the input was valid.
You would have had more of a clue about what is going on if you had provided more feedback to the user. It is very unfriendly to reject an input without giving any notice that you have done so or any way for the user to recognize it. At least two reasonable feedback mechanisms could be easily integrated:
Update the prompt to tell the user for which train an ID is being requested:
printf("Enter the ID for Train %d :\n", count);
Add an else block to your validation test that, when executed, prints a message explaining that the ID was rejected.
I would probably do both, but the latter is the one that would make it clear that your if condition itself is working as expected. The former would help you recognize that the loop requests an ID only once for each train, regardless of whether a valid one is provided. It stores only valid IDs, but it never prompts for a replacement ID for an invalid one.
Related
EDIT: I am so sorry for the inconvenience but I had to take out the original code that I had used to submit this question. I will reupload my old code and the new code later! But the answer that is still up was very helpful in understanding how to track the number of inputs that are inputted by a user using a do ... while loop.
For this assignment, we were supposed to create a random guessing game where user inputs a number between 1 and 100 and has 3 functions (int getRandomNumber(void), int check4Win(int,int) and void printResults(int)). getRandomNumber was just made to create the random number, check4Win was just to tell the user if their guess is too high, too low, or correct and for printResults we are supposed to rank the user based on how many guesses they inputted. My issue is with printResults and what goes in main to actually keep track of how many guesses the user inputted. I was able to get the entire code to work but my main issue is being able to keep track of the number of inputs because what I have now is printing out the first input rather than the number of inputs. I will include my entire code but the main issue is printResults. The rest of them seem fine but if you think there is an issue somewhere else please let me know! I know that I used a switch statement inside the for statement in main and I am about 99.9% sure that is wrong I just couldn't figure out what else to do. Also, the formatting is off a bit here but that's just so that the code can stay together its formatted fine on my compiler! I am also fairly new to so I will take all criticism.
Thank you!
Here is a very simple example of how to count "guesses" until success. You can extend as you see fit, whether that is to move stuff into functions, add "maximum guesses" logic, use proper input handling (this will break if you input a non-integer, like hello).
int randNum = getRandomNumber();
int guessNum = 0;
int guessCount = 0;
do {
printf("Guess #%d: ", guessCount + 1);
scanf("%d", &guessNum);
// validate
if (guessNum < 1 || guessNum > 100)
{
printf("Invalid guess\n");
continue;
}
++guessCount;
// check
if (guessNum < randNum)
printf("Too low\n");
else if (guessNum > randNum)
printf("Too high\n");
} while(guessNum != randNum);
printf("Total guesses: %d\n", guessCount);
My advice is you manage input in one place. I couldn't stomach the way you're doing input in main, but then the "check4win" function tries to input values too. A function should do what its name implies. That function "checks" something, so one would expect that it returns some kind of value that indicates the result of "checking". That's all it should do. Since it's called "check4Win", I would expect it returns true if the guess "wins" and false otherwise.
Currently, I am experimenting some codes regarding/about random numbers. The problem is, when I run the program, input any number (ex. 12), I, sometimes get the correct and sometimes wrong answer. The correct answer must be any non repeating random numbers based on user input. (ex. input 5, output must be 1. seats[12]=1, 2. seats[19]=1,..., 5. seats[47]=1). I do not know what to do and yeah help me coders!
Here's the code:
#include<stdio.h>
#include<conio.h>
#include<time.h>
main()
{
int x,y,chc1A,seats[50]={};
printf("Enter a number: ");
scanf("%d",&chc1A);
srand(NULL);
for(x=0;x<chc1A;x++)
{
if(seats[rand()%50]==0)
seats[rand()%50]=1;
else
x--;
}
for(x=0,y=1;x<50;x++)
if(seats[x]==1)
{
printf("%d. seats[%d] = %d\n",y,x,seats[x]);
y++;
}
getch();
}
I do not really know what's wrong please enlighten me.
I run and coded this on Dev C++
What I want to do is: generate random numbers between 0-49 and putting it in an array seats[50]. (ex 38 then put 1 in array seats[38]). Btw this code represents passengers sitting on a bus with 50 seats. So the "1" means that the seat is occupied.
This part may cause problem.
for(x=0;x<chc1A;x++)
{
if(seats[rand()%50]==0)
seats[rand()%50]=1;
else
x--;
}
I think by
if(seats[rand()%50]==0)
seats[rand()%50]=1;
you meant to generate a random number, use that as index to seats and if seats[random_no] is 0, set seats[random_no] to 1.
But the random number in the if statement and the one in its body are different numbers.
You could use
int index = rand()%50;
if(seats[index]==0)
seats[index]=1;
Consider changing the signature of your main() function. See What are the valid signatures for C's main() function?
conio.h is not part of the standard, try to avoid its usage. Same goes for getch() as it's from conio.h.
srand() expects an unsigned int as argument and NULL is not of that type. See here.
Include stdlib.h to use srand().
And checking the return value of scanf() is a good idea. You can see if it failed or not.
This assignment consists of two tasks.
Task 1:
a) Create a program that reads numbers from the user until the user provides the number 0. (Without doing anything with numbers). Use a while loop to achieve this.
I made this code to achieve this:
import java.util.Scanner;
public class HelloPrinter {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int ditt_tall = 1;
while(ditt_tall != 0) {
System.out.print("Skriv inn ditt tall: ");
ditt_tall = in.nextInt();
}
}
}
This is the task in task 2:
b) Expand the program to sum all the numbers from the user (until user
give the number 0) and write the result to the terminal
To be honest. I have no idea what to do. Can someone give me a hint or expand the first code so it works the way it should?
Make a variable to save the total, before your while loop starts and set it to zero. Inside your loop, accept the input and add it to your total value. After the loop ends, print out your total variable value.
So, in addition to your
int ditt_tall = 1;
create your total variable there too, like
int ditt_total = 0;
inside your loop, you can increment the total with the value that is input:
ditt_total = ditt_total + ditt_tall;
And after the loop ends, print out the value of ditt_total.
Go through the code by hand, pretending to input numbers, and seeing how ditt_tall and ditt_total change with each loop. Using paper is a good way to understand what the program is doing, and also helps figure out what is going wrong when the results are not what you expect.
Here are some things to consider, however: what happens if the user enters a string or decimal number? Maybe at this point you don't have to deal with that, but bad input is a problem you'll always need to consider in real life.
Solving the question by Memoization without the help of Maps, I got a TLE due to the method of reading the file, which shouldn't have been the case according to me. What could be the possible reason?
Here is the code that gives AC - http://ideone.com/OX1XlD
In the above code, for scanning n, if the while(scanf("%lld",&n)!=EOF) is replaced by
scanf("%lld",&n)
while(n!=EOF){ do something
scanf("%lld",&n);
}
the same gives a TLE. I can't figure out why.
I did not check your code in the link, but from the code in the question, in case of while(scanf("%lld",&n)!=EOF), you're checking the return value of scanf() itself.
OTOH, by saying
scanf("%lld",&n)
while(n!=EOF){
you're checking the value of n, which, is a completely different case and in case of scanf() failure, is undefined behaviour, if n is not initialized earlier.
The correct and preferred method,Thanks to Mr. Weather Vane will be to check against the number of items in scanf(), like
if (1 != scanf("%lld",&n))
or,
while ( 1 == scanf("%lld",&n)) //as in this case
EOF is a corner case and is usually rare.
In response to a recent comment by OP I suggest he tries this.
#include <stdio.h>
int main(void) {
long long int n;
char instr[20];
while (1 == scanf("%lld", &n)) {
printf ("The entry was %lld\n", n);
}
printf("End of file\n");
return 0;
}
The SPOJ will test your code by feeding it input from a file. Let's say inp.txt has
1
2
3
4
You then run your code with something like (in the case of Windows console)
coins <inp.txt
and this gives me the output
The entry was 1
The entry was 2
The entry was 3
The entry was 4
End of file
If this works, and your program still exceeds the time limit, you must look at your solution algorithm, since SPOJ gives no clues as to why you have a TLE.
Of course, your submitted solution must not print those cues since the output will fail the test.
This question already has answers here:
Why does scanf get stuck in an infinite loop on invalid input? [duplicate]
(2 answers)
Closed 8 years ago.
This is a bit of a long post so bear with me. The gist of what I am trying to do is get some user input at the beginning of a loop, do some things depending on that input and possibly repeat. Simple enough right? Here is what I have.
void displayMain(Album albums[], int num_albums){
int break_condition = 1;
int user_choice;
//keep looping until we decide to quit
while (break_condition){
user_choice = displayMenu();
switch(user_choice){
case 0 :
return; //does this need to be return 0 or can it just be return (or is it the same thing?)
case 1 :
displayAlbums(albums, num_albums);
break;
case 2 :
printf("display tracks\n");
break;
default :
printf("Invalid choice!\n\n");
break;
}
}
return;
}
The function displayMenu() basically grabs some user input and returns an int.
int displayMenu(void){
printf("Display Menu\n1. Display all albums\n2. Display the tracks in an album\n0. Return to the mainmenu\nPlease enter the choice:\n");
//grab and return the choice
int choice;
scanf("%d", &choice);
return choice;
}
So when I finally run all of this code, if I enter a "bad" choice, ie: one that takes the default path in the switch statement, the code enters an infinite loop. Repeating the contents
Display Menu
1. Display all albums
2. Display the tracks in an album
0. Return to the main menu
Please enter the choice:
Invalid choice!
I am pretty much a newb at C, so I believe I know why this is. user_choice is not ever being reset, even though the function displayMenu is clearly being called (because of the infinite loop output)
Why isn't displayMenu asking the user for input anymore after one instance of "bad" input is entered? Is it because it isn't an integer? When I tried debugging and printing out user_choice, it was some large number, so likely a register or something like that.
Please help, as I said, I suck at C, so an experienced C programmer could probably lend a hand :)
Running your code in Visual Studio 2012 (in the Cygwin Terminal executing it as a .c extension that I also tested , it works just fine) the only error that I got was that I should use the safe version of scanf( scanf_s ) instead.
If you don't want doing that the whole time when you already have declared more than one scanf in your code and the specific error pops up, you could add to your preprocessor definitions the _CRT_NO_SECURE_WARNINGS sentence . Still, I don't know the exact implications of using
the scanf_s over scanf and the opposite and how it affects the input of a program.
[ Right Click on your project--> Properties--> C/C++ -->Preprocessor Definitions and you add the sentence . ]
All the above I guess only apply if your IDE is Visual Studio and that is your case.
As for the return statement in case 0. This will force the loop to terminate and thus, it will exit the function . You can use the break statement to end processing of a particular case within the switch statement and to branch to the end of the switch instead, so the loop can be continued and display your menu again.
Returning a 0 value type will not match your function type ( as long as you have it declared as void ).