In this code, I try to code to keep customer data to keep in an array list. I need to keep first name, last name, contact number, and payment method.
public static void Rent()
{
WriteLine("Enter your first name");
input_fname = ReadLine();
WriteLine("Enter your last name");
input_lname = ReadLine();
WriteLine("Enter your contact number");
input_phone = ReadLine();
WriteLine("Enter your payment method");
input_payment = ReadLine();
ArrayList arr_cust = new ArrayList();
for (int i = 0; i <= arr_cust.Count; i++)
{
arr_cust.Add(input_fname + input_lname + input_phone + input_payment);
}
WriteLine("Pease enter 1 to return to previous menu and 0 to exit");
int input = Convert.ToInt32(ReadLine());
bool exit = false;
while (exit == false)
{
if (input == 1)
{
Main();
}
else if (input == 0)
{
WriteLine("Thank you for use Rental E-Bike System");
System.Environment.Exit(0);
}
else
{
}
}
}
My problem is when I put all of the value that i need to keep and after the I put 1 to back to main page. Next, I open Rent page again to put the second of value to keep in array list. Next step, I need to show data which I keep in array list.
Your Rent function creates a new instance of ArrayList each time it is invoked and that is why arr_cust is always empty and the only value it has is the one you insert within the Rent function.
Instead of initializing arr_cust within Rent you can initialize it as a static field outside of the function so it retains the previous values.
Also you do not need the for loop to insert your data. You are inserting only once and with the for loop you are going to get N duplicates of that entry. N being the previous item count.
public static ArrayList arr_cust = new ArrayList();
public static void Rent(ArrayList arr_cust)
{
WriteLine("Enter your first name");
input_fname = ReadLine();
WriteLine("Enter your last name");
input_lname = ReadLine();
WriteLine("Enter your contact number");
input_phone = ReadLine();
WriteLine("Enter your payment method");
input_payment = ReadLine();
arr_cust.Add(input_fname + input_lname + input_phone + input_payment);
WriteLine("Pease enter 1 to return to previous menu and 0 to exit");
int input = Convert.ToInt32(ReadLine());
bool exit = false;
while (exit == false)
{
if (input == 1)
{
Main();
}
else if (input == 0)
{
WriteLine("Thank you for use Rental E-Bike System");
System.Environment.Exit(0);
}
}
}
Related
I am very new to C# and I have just created my first program, which is your classic "number guesser".
In my program, after the user has guessed the correct number, I want to give them an option where they can either type "Y" or "N" to continue or end the game.
Where my issue lies is, if the user were to type in the letter "G" at this stage, the program would continue and ask the user to input another number.
How do I enable my code to keep looping at this stage until either Y is pressed to continue the game or N is pressed to end the program?
using System;
// Namespace
namespace NumberGuesser
{
// Main Class
class Program
{
// Entry Point Method
static void Main(string[] args)
{
GetAppInfo(); // Run GetAppInfo function to get info
GreetUser(); // Ask for user's name and greet
while (true)
{
// Create a new Random object
Random random = new Random();
// Initial correct number
int correctNumber = random.Next(1, 11);
// Initial guess var
int guess = 0;
// Ask user for number
Console.WriteLine("Guess a number between 1 and 10:");
// While guess is not correct
while (guess != correctNumber)
{
// Get users input
string input = Console.ReadLine();
// Make sure it's a number
if (!int.TryParse(input, out guess))
{
// Print error message
PrintColourMessage(ConsoleColor.Red, "Please user an actual number.");
// Keep going
continue;
}
// Make sure the number guessed is between 1 - 10
if (guess > 10)
{
// Print error message
PrintColourMessage(ConsoleColor.Red, "Please enter a number from 1 to 10.");
// Keep going
continue;
}
// Cast to int and put in guess
guess = Int32.Parse(input);
// Match guess to correct number
if (guess != correctNumber)
{
// Print error message
PrintColourMessage(ConsoleColor.Red, "Wrong number, please try again.");
}
}
// Print success message
PrintColourMessage(ConsoleColor.Yellow, "You are CORRECT!!!");
// Ask to play again
Console.WriteLine("Play again? [Y or N]");
// Get answer
string answer = Console.ReadLine().ToUpper();
if (answer == "Y")
{
continue;
}
else if (answer == "N")
{
return;
}
else
{
return;
}
}
}
// Get and display app info
static void GetAppInfo()
{
// Set app vars
string appName = "Number Guesser";
string appVersion = "1.0.0";
string appAuthor = "Jack Thomas";
// Change text colour
Console.ForegroundColor = ConsoleColor.Green;
// Write out app info
Console.WriteLine("{0}: Version {1} by {2}", appName, appVersion, appAuthor);
// Reset text colour
Console.ResetColor();
}
// Ask user's name and greet
static void GreetUser()
{
// Ask users name
Console.WriteLine("What is your name?");
// Get user input
string inputName = Console.ReadLine();
Console.WriteLine("Hello {0}, let's play a game...", inputName);
}
// Print colour message
static void PrintColourMessage(ConsoleColor color, string message)
{
// Change text colour
Console.ForegroundColor = color;
// Prints message
Console.WriteLine(message);
// Reset text colour
Console.ResetColor();
}
}
}
Just instead of doing this:
// Ask to play again
Console.WriteLine("Play again? [Y or N]");
// Get answer
string answer = Console.ReadLine().ToUpper();
if (answer == "Y")
{
continue;
}
else if (answer == "N")
{
return;
}
do that:
// Ask to play again
Console.WriteLine("Play again? [Y or N]");
bool toContinue = false;
bool invalidResponse = true;
while(invalidResponse) {
// Get answer
string answer = Console.ReadLine().ToUpper();
if (answer == "Y")
{
toContinue = true;
invalidResponse = false;
}
else if (answer == "N")
{
invalidResponse = false;
}
}
if(toContinue != true) return;
I've created while loop wich loops while invalidResponse variable is true, invalidResponse is true when we not entered any of these characters "Y" or "N".
You can also make Console.WriteLine when user enters invalid response.
If user does not entered "Y" it sets toContinue to false and it ends program.
Trying to complete a stock system in a console application and thus I am stuck on this part, to make sure that a user can't have a duplicate 8 digit long ID number, my issue is as follows.
Basically I am unsure why this code will not work, I'm probably missing a very obvious piece of code here, help would be appreciated, have tried changing values around already so have more than likely overlooked a value.
static int checkIDNumber(int ID)
{
// Check the number passed in & then loop through all the lines...
// If number is taken then output error, because id exists already
// Else allow the value to be used in the stock system.
int IDNumber = ID;
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
string lineValues;
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
Console.WriteLine("Id number is currently already taken.");
}
else
{
return IDNumber;
}
}
}
}
I pass in my value from this line in another procedure where it is defined in the local scope.
stockID = checkIDNumber(stockID);
Here is the full code:
class Program
{
static void Main(string[] args)
{
char menuOption = '0';
while (menuOption != '3')
{
DisplayMenuOption();
menuOption = GetMenuOption();
switch (menuOption)
{
case '1':
AddStock();
break;
case '2':
CheckStock();
break;
case '3':
Console.WriteLine("Goodbye");
break;
default:
Console.WriteLine("That is not a valid option");
break;
}
}
// Keep it all happy for a screenshot ;)
Console.ReadLine();
}
static void DisplayMenuOption()
{
Console.WriteLine("Do you wish to Add Stock(1) or Check Stock(2) or Exit(3)?");
}
static void DisplayStockOption()
{
Console.WriteLine("Do you want to search by ID(1) or by Name(2), Delete current stock(3) or Exit(4)?");
}
static char GetMenuOption()
{
char userChoice = '0';
userChoice = Convert.ToChar(Console.ReadLine());
return userChoice;
}
static void CheckStock()
{
char menuOption = 'a';
while (menuOption != '4')
{
DisplayStockOption();
menuOption = GetMenuOption();
switch (menuOption)
{
case '1':
SearchID();
break;
case '2':
SearchName();
break;
case '3':
RemoveStock();
break;
case '4':
Console.WriteLine("Goodbye");
break;
default:
Console.WriteLine("That is not a valid option");
break;
}
}
}
static void RemoveStock()
{
List<string> tempList = new List<string>();
string lineValues = "";
bool found = false;
int ID = 0;
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
Console.Write("Please enter the ID number to delete: ");
ID = Convert.ToInt32(Console.ReadLine());
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(ID.ToString()) == false)
{
tempList.Add(lineValues);
}
else
{
found = true;
}
}
}
if (found == true)
{
using (StreamWriter sw = new StreamWriter("Stockfile.txt", false))
{
for (int i=0; i < tempList.Count; i++)
{
sw.Write(tempList[i]);
sw.WriteLine();
}
}
}
}
static void SearchName()
{
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
string name;
Console.Write("Please enter the name: ");
name = Console.ReadLine();
while (sr.EndOfStream == false)
{
string lineValues = sr.ReadLine();
if (lineValues.Contains(name))
{
Console.WriteLine("{0}", lineValues);
}
else
{
Console.WriteLine("{0} does not exist in this stock system!",name); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match.
}
}
}
}
static void SearchID()
{
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
int IDNumber;
string lineValues;
Console.Write("Please enter the ID number: ");
IDNumber = Convert.ToInt32(Console.ReadLine());
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
Console.WriteLine("{0}", lineValues);
}
else
{
Console.WriteLine("{0} does not exist in this stock system!", IDNumber); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match.
}
}
}
}
static int checkIDNumber(int ID)
{
// Check the number passed in & then loop through all the lines...
// If number is taken then output error, becuase id exists already
// Else allow the value to be used in the stock system.
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
int IDNumber;
string lineValues;
Console.Write("Please enter the ID number: ");
IDNumber = Convert.ToInt32(Console.ReadLine());
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
Console.WriteLine("Id number is currently already taken.");
}
else
{
ID = IDNumber;
return ID;
}
}
}
}
static void AddStock(int IDNumber)
{
using (StreamWriter sw = new StreamWriter("Stockfile.txt", true))
{
int stockID = 0;
int stockQuantity = 0;
double stockPrice = 0.00;
string stockName = "";
string s = ""; // Being Lazy here, to convert to when needed.
while (stockID.ToString().Length != 8)
{
Console.Write("Please enter the stock ID number: ");
stockID = Convert.ToInt32(Console.ReadLine());
}
s = stockID.ToString();
sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here.
while (stockName.Length <= 2) // No fancy brands here......
{
Console.Write("Please enter the name of the stock: ");
stockName = Console.ReadLine();
}
s = stockName;
sw.Write(s + "\t");
while (stockQuantity < 1) // Running a small shop here...
{
Console.Write("Please enter the quanity of stock: ");
stockQuantity = Convert.ToInt32(Console.ReadLine());
}
s = stockQuantity.ToString();
sw.Write(s + "\t");
while (stockPrice < 0.01) // Running a very small shop....
{
Console.Write("Please enter the price of the stock: ");
stockPrice = Convert.ToDouble(Console.ReadLine());
}
s = stockPrice.ToString();
sw.Write(s + "\t");
sw.WriteLine(); // TO create the new line.....
}
}
}
}
The problem is that you're only returning a value from inside the else block.
Your method needs to return a value regardless of which path the program takes through your code. You can fix this in any number of ways, depending on your requirements. For instance, you can have a "catch-all" return value at the bottom of the method so that if it passes through all your tests (i.e. if blocks) and reaches the bottom, as long as that's a meaningful result, it will return the catch-all value.
Alternatively, you could just make sure you put a return statement inside each of the code paths. For that, you'd need to add a return in the if portion of your if block, but you'd likely also still need a return outside of your while loop since that may never execute.
Again, it all depends on your needs.
It's at least logically possible that the file contains nothing but the ID. For example, if I enter "10" as an ID and the file is:
10
10
10
10
...
It might be the case that you know that that'll never actually happen, but the compiler can't really prove that it won't. From the compiler's "perspective," there's not really a difference between "might happen" and "can't prove that it won't happen."
Also, your logic is wrong. If you know that the user requested a duplicate ID, you don't need to check the rest of the file - you already know it's a duplicate.
Right now, if the first line of the file isn't the ID they requested, it'll allow the user to take it. For example, if the user requested "9" as an ID and the file is as follows:
3 -- It only actually checks this line
5
9 -- Obviously the ID is already taken here but it'll never check this line
2
1
See my comments below:
// I'd suggest making this "bool" - they already know what the ID number is,
// so there's no point in returning it back to them
static int checkIDNumber(int ID)
{
// Check the number passed in & then loop through all the lines...
// If number is taken then output error, because id exists already
// Else allow the value to be used in the stock system.
int IDNumber = ID;
using (StreamReader sr = new StreamReader("Stockfile.txt"))
{
string lineValues;
// In general, you shouldn't explicitly compare to "true" or "false."
// Just write this as "!sr.EndOfStream"
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
if (lineValues.Contains(IDNumber.ToString()))
{
// In this case, you don't have to bother checking the rest of the file
// since you already know that the ID is taken
Console.WriteLine("Id number is currently already taken.");
}
else
{
// You actually can't return that at this point - you need to check
// the *entire* file before you conclude that it's not a duplicate
return IDNumber;
}
}
}
}
This code throws a Format Exception when a wrong input is input by the user at the conversion of the string to int. It also doesn't reach the desired output of "All first class seats have been booked" when 32 tickets have been sold, it just throws an index out of range exception. Any help with this would be greatly appreciated. Thanks.
class FirstClassCompartment
{
public void FirstClassTickets()
{
bool[] seats = new bool[32];
List<int> seatsBooked = new List<int>();
int completeBooking = 0;
bool quit = false;
string ticketAmount = "";
int firstClassSeat = 0;
int convertedTicketAmount;
{
Groups firstClass = new Groups();
Console.Clear();
Console.WriteLine("\nWelcome to the First Class booking menu");
Console.WriteLine("");
Console.WriteLine("Please enter the amount of tickets you would like to book");
ticketAmount = Console.ReadLine();
Console.Clear();
Console.WriteLine("\nFirst Class booking menu");
convertedTicketAmount = Convert.ToInt32(ticketAmount);
ticketAmount = firstClass.NumberInGroupFirstClassWest;
}
do
{
Console.Clear();
Console.WriteLine("\nFirst Class booking menu");
Console.WriteLine("");
Console.WriteLine("Please press 1 to complete your first class booking");
completeBooking = Int32.Parse(Console.ReadLine());
switch (completeBooking)
{
case 1:
if (seatsBooked.Count == 0)
{
firstClassSeat++;
seats[firstClassSeat] = true;
seatsBooked.Add(firstClassSeat);
}
else
{
do
{
firstClassSeat++;
if (!seatsBooked.Contains(firstClassSeat))
{
seats[firstClassSeat] = true;
}
}
while (seatsBooked.Contains(firstClassSeat) && seatsBooked.Count < 32);
if (seatsBooked.Count < 32)
{
seatsBooked.Add(firstClassSeat);
}
}
if (seatsBooked.Count > 32)
{
Console.WriteLine("All seats for first class have been booked");
Console.WriteLine("Please press enter to continue...");
}
else
{
Console.WriteLine("Your seat: {0}", firstClassSeat + 1);
Console.WriteLine("Please press enter to continue...");
}
Console.ReadLine();
break;
default:
Console.WriteLine("\nPlease enter a valid input");
quit = true;
break;
}
} while (!quit);
}
}
You need to use Int32.TryParse and check the returned bool.
Look at the logic in you switch statement, you only handle a booking of 1. What if the user books 2 seats?
Edit: Sorry, just realised that switch statement is to handle the menu, not number of bookings
Do you need a list of ints, as well as an array of bools in order to track how many seats have been booked? Couldn't you just use a plain old int, e.g. numberOfSeatsBooked? Then you can do numberOfSeatsBooked += convertedTicketAmount;
I would do this very differently. You should have a class for seats containing a boolean for booked and iterate that rather than a random array of books that may or may not be linked to a random list of booked seats and a number of seats booked. Here's a small example:
public class Seat
{
public int SeatNo { get; set; }
public bool FirstClass { get; set ; }
public bool Booked { get; set; } // could actually be an instance of a booking info class including name and ticket id, etc.
}
public class Flight
{
public List<Seat> Seats = new List<Seat>();
private int _lastSeat = 0;
public void AddSeats(int num, bool firstClass)
{
for (int i = 0; i < num; i++)
{
_lastSeat++;
Seats.Add(new Seat { SeatNo = num, FirstClass = firstClass });
}
}
public int BookNextAvailableSeat(bool firstClass)
{
foreach (Seat seat in Seats.AsQueryable().Where(x => x.FirstClass == firstClass)
{
if (!seat.Booked)
{
seat.Booked = true;
return seat.SeatNo;
}
}
return null;
}
}
Then your:
case 1:
int booking = flight.BookNextAvailableSeat(true);
if (booking != null)
Console.WriteLine("Your seat: {0}", booking);
else
Console.WriteLine("All seats for first class have been booked");
Console.WriteLine("Please press enter to continue...");
break;
Of course you need to instantiate flight and add the 32 seats using:
Flight flight = new Flight();
flight.AddSeats(32, true);
I'm a newbie at C# and I'm having some difficulties writing a program that is going to let you save values in a variable, everything is working fine, except I can't save values into my variable. Here's the code:
while (true)
{
//Menu
Console.WriteLine (" \n\tWelcome!");
Console.WriteLine (" \t[1]Store value");
Console.WriteLine (" \t[2]Write message");
Console.WriteLine (" \t[3]Clear the console");
Console.WriteLine (" \t[4]Shut down program");
Console.Write("\tChoose: ");
//Users choice
int choice = Convert.ToInt32 (Console.ReadLine ());
//Users message
string usrMsg = null;
//if statement
if (choice == 1) {
usrMsg += Console.ReadLine ();
} else if (choice == 2) {
Console.WriteLine (usrMsg);
} else if (choice == 3) {
//Shuts down program
break;
} else if (choice == 4) {
//Clear program
Console.Clear ();
}
else
{
Console.WriteLine("please enter a number between 1-4");
}
}
You just move the usrMsg variable out of while block as a global the value will be saved.
//Users message
string usrMsg = null;
while (true)
{
//Menu
Console.WriteLine(" \n\tWelcome!");
Console.WriteLine(" \t[1]Store value");
Console.WriteLine(" \t[2]Write message");
Console.WriteLine(" \t[3]Clear the console");
Console.WriteLine(" \t[4SShut down program");
Console.Write("\tChoose: ");
//Users choice
int choice = Convert.ToInt32(Console.ReadLine());
//if statement
if (choice == 1)
{
usrMsg += Console.ReadLine();
}
else if (choice == 2)
{
Console.WriteLine(usrMsg);
}
else if (choice == 3)
{
//Shuts down program
break;
}
else if (choice == 4)
{
//Clear program
Console.Clear();
}
else
{
Console.WriteLine("please enter a number between 1-4");
}
}
When this runs it always creates userMsg as null. That means that at best it will 'save' only 1 value when the user chooses '1'. However, this will never get displayed if the user selects '2' as when the user gets to the menu again userMsg will have been set to null again.
My assumption is that you're trying to save the number of times someone has selected '1' and then display that if the user then hits option '2'.
Stick this:
//Users message
string usrMsg = null;
outside of the 'while' loop.
Pretend that I'm asking the user to input an album to list down.
I have this fine,
but for some reason I cant figure out a way for them to be able to then delete the input that they have made.
This is the method that I have used to store any album input that they have
static void InsertNewAlbum()
{
//Variable for user input
string albumInput
//Ask for the user for details
Console.WriteLine("Enter the Title of the album you would like to store");
albumInput = Console.ReadLine();
//Process the input of the user to make it easier to search later on
albumInput = albumInput.ToUpper();
albumInput = albumInput.Trim();
//Find an empty spot within list
int nextAvailableSpace = FindSlot("");
if (nextAvailableSpace != -1)
{
//Put customer information within an empty slot into the car park
albumNames[nextAvailableSpace] = albumInput;
}
else
{
//Inform that the usercannot park as the parking space is full
Console.WriteLine("Sorry, but there are no available spaces left to store your album.");
Console.ReadLine();
}
}
Here's the how the "FindSlot" method goes, for anyone that curious
static int FindSlot(string albumName)
//Finding an empty slot for the user to put their car in
{
int result = - 1;
for (int index = 0; index < albumNames.Length; index++)
{
if (albumNames[index] == albumNames)
{
result = index;
break;
}
else if (albumName == "" && albumNames[index] == null)
{
result = index;
break;
}
}
return result;
}
albumNames is the string that it puts in album the customer puts in and it's a static string.
So yeah, the user can freely put in 10 albums, but when it comes to deleting an album I get stuck.
The album is listen within a string array. I've tried various things within my knowledge but nothing seems to be working.
Thanks for anyone that can help, it is quite complicated.
You always send "" to FindSlot, as you should be sending the albumInput. If you need to know if the album is present, first control all the albumNames if your input is present, then look for a space. Like:
static int FindSlot(string albumName)
//Finding an empty slot for the user to put their car in
{
for (int index = 0; index < albumNames.Length; index++)
{
if (albumNames[index] == albumName)
{
return index;
}
}
for (int index = 0; index < albumNames.Length; index++)
{
if (albumNames[index] == "")
{
albumNames[index] = albumName;
return index;
}
}
return -1;
}
And call it like:
static void InsertNewAlbum()
{
//Variable for user input
string albumInput;
//Ask for the user for details
Console.WriteLine("Enter the Title of the album you would like to store");
albumInput = Console.ReadLine();
//Process the input of the user to make it easier to search later on
albumInput = albumInput.ToUpper();
albumInput = albumInput.Trim();
//Find an empty spot within list
int nextAvailableSpace = FindSlot(albumInput);
if (nextAvailableSpace != -1)
{
Console.WriteLine(albumInput + " is stored successfully at slot" + nexAvailableSpace + "");
}
else
{
//Inform that the usercannot park as the parking space is full
Console.WriteLine("Sorry, but there are no available spaces left to store your album.");
}
Console.ReadLine();
}
To delete; you can use a similar function:
static int DeleteAlbum(string albumName)
//Finding an empty slot for the user to put their car in
{
for (int index = 0; index < albumNames.Length; index++)
{
if (albumNames[index] == albumName)
{
albumNames[index] = "";
return index;
}
}
return -1;
}
As your FindSlot function, you can return an integer to confirm deletion was successful. Like:
static void DeleteAnAlbum()
{
//Variable for user input
string albumInput;
//Ask for the user for details
Console.WriteLine("Enter the Title of the album you would like to store");
albumInput = Console.ReadLine();
//Process the input of the user to make it easier to search later on
albumInput = albumInput.ToUpper();
albumInput = albumInput.Trim();
//Find and delete the album from the List
int deletedIndex = DeleteAlbum(albumInput);
if (deletedIndex != -1)
{
Console.WriteLine(albumInput + " is deleted successfully");
}
else
{
//Inform that the usercannot delete
Console.WriteLine("Sorry, but there are no albums with given name.");
}
Console.ReadLine();
}
This code is not good, but I tried to keep your style.