Why when I type "gamble" the first time, only the if statement works? It's no use typing anything else, it still adds 10 woods. And why when I type anything else the first time, just the else statement works? It is no use typing "gamble, will continue saying " Write '' gamble '' to hit the tree. " PS: The variable its int = woods; and string gamble;
Console.WriteLine("You have {0} woods", woods);
Console.WriteLine("Write ''gamble'' to hit the tree");
gamble = Console.ReadLine();
bool loop = true;
while (loop)
{
if (gamble.Contains("gamble"))
{
woods = woods + 10;
Console.Clear();
}
else
{
Console.WriteLine("Write ''gamble'' to hit the tree");
}
Console.WriteLine("You have {0} woods", woods);
Console.ReadLine();
}
gamble = Console.ReadLine();
You only set gamble in the beginning. In the loop it is never changed. So it keeps using the first value over and over again.
Add gamble = to the last line of the loop.
If I understand what your are describing, you forgot to read into gamble again
Console.WriteLine("You have {0} woods", woods);
gamble = Console.ReadLine();
}
At the end of the while loop, you are doing Console.ReadLine() but not storing it. You need gamble = Console.ReadLine() to store the scanned string in the "gamble" variable.
Because loop is always true. You should change it to false after if and else statements...
The reason it's adding 10 wood regardless if there is something else than "gamble" in the console line, is because you're writing "gamble" in the returning message.
else {Console.WriteLine("Write ''gamble'' to hit the tree");} is the problem here.
You can fix it by either not writing the word "gamble" inside the returning message, or find a clever way to not have it run in a while(true) loop.
You can, for example, use the main method to have it run the function you're going to run just once.
Something like this.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
class Program
{
// Set a `wood` variable for the class.
protected int wood { get; set; }
static void Main(string[] args)
{
Program program = new Program(); // Making use of non-static methods.
program.Handler();
}
public void Handler()
{
Console.WriteLine("Write \"gamble\" to hit the tree.");
string message = Console.ReadLine();
if (message == "gamble")
{
addWood(); // Call the non-static method.
}
}
public bool addWood()
{
this.wood = this.wood + 10;
Console.WriteLine("You now have {0} wood!", this.wood);
Handler(); // Call the Handler() method again for infinite loop.
return true;
}
}
}
WARNING: The program will exit if there is something else than "gamble" written.
Related
Im trying to learn loops and they are on the verge of breaking me. This loop has either not worked at all or never ended which has lead to some serious stress. If anyone could help me out it would be great. The plan is for the loop to continue until someone writes yes/Yes/YES (any form of yes preferably) and then break and continue the next part of the code which is some readlines and write lines, haven't gotten that far because the loop hasn't let me yet. Very thankful for any input.
Console.WriteLine("Hello Inspector!");
Console.WriteLine("Are you ready to identify the suspects? Just write yes and we'll get started.");
string Start = Console.ReadLine();
Startup();
while (Start.Contains("")==false)
{
Console.WriteLine("Just type yes when you are ready.");
if (Start.Contains("Yes") == true)
Console.WriteLine("Let's start.");
break;
}
}
static void Startup()
{
string Start = Console.ReadLine();
if (Start.Contains("yes") == true)
{
Console.Clear();
Console.WriteLine("Here are the suspects:");
}
else
{
Console.WriteLine("Just type yes when you are ready.");
}
}
}
}
There are several issues with your code:
1) You only once read user input - as m.sh already noted, you need to put
Start = Console.ReadLine();
inside your while loop.
2) Your break you expect only to catch if your condition is met is outside the scope because you are missing enclosing { } like this:
if (Start.Contains("Yes") == true)
{
Console.WriteLine("Let's start.");
break;
}
3) Not directly a programming bug but widely frowned upon: explicitly comparing boolean. Simply use
if (Start.Contains("yes"))
instead of
if (Start.Contains("yes") == true)
4) Also already mentioned - use .ToLower() to allow any input casing
if (Start.ToLower().Contains("yes"))
will work for yes, YES, yEs, YeS, ...
Putting together the parts for a working loop
// many coding guidelines ask you to use string.Empty rather than "". [I.]
string Start = string.Empty;
while (!Start.ToLower().Contains("yes"))
{
Console.WriteLine("Just type yes when you are ready.");
Start = Console.ReadLine();
}
Console.WriteLine("Let's start.");
Note the negation ! for the while condition - this makes your loop run as long as the condition is not met instead of having to check inside your loop if you need to break out.
Another way to loop could be do { } while(); where your condition is checked at the end of the loop:
string Start = string.Empty;
do
{
Console.WriteLine("Just type yes when you are ready.");
Start = Console.ReadLine();
}
while (!Start.ToLower().Contains("yes"));
If you step through your code running in debugger, you will notice the different behavior and how do {} while() can be considered faster code than while() { }.
I. In C#, should I use string.Empty or String.Empty or “” to intitialize a string?
I have coded a system based of the theory that while loops can work anywhere in a system. So once a while loop has been passed by it can run. Here is a simple version of my code:
using System;
namespace test___login
{
class Program
{
static void Main(string[] args)
{
string location = "homepage";
while (location.Equals("Homepage", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("homepage");
Console.WriteLine("WHere to now: ");
location = Console.ReadLine();
}
while (location.Equals("login", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("login");
Console.WriteLine("Where to now: ");
location = Console.ReadLine();
}
}
}
}
So I assumed that once the variable changes from "login" to "homepage" in the second while loop, would mean the first while loop would run once again. Is my theory on how the code works wrong or am i simply not typing the right thing. I just started last week so sorry for the basic question
It wouldn't run again, because the code has already executed past that line so unless you call it again, the next thing down the line will execute, in your case nothing - this is called procedural programming.
Why don't you make one while loop, and a switch statement instead.
bool run = true;
while (run)
{
Console.WriteLine("WHere to now: ");
string location = Console.ReadLine();
switch(location.ToLower()){
case "homepage":
Console.WriteLine("HomePage");
break;
default:
run = false;
break;
}
}
Not with the way you have your code currently structured. It will exit the application. You need to surround all of that with one more while loop, which can be similar to your other loops. See below:
using System;
namespace test___login {
class Program
{
static void Main(string[] args)
{
string location = "homepage";
while (!location.ToUpper().Equals("EXIT"))
{
while (location.Equals("Homepage", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("homepage");
Console.WriteLine("WHere to now: ");
location = Console.ReadLine();
}
while (location.Equals("login", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("login");
Console.WriteLine("Where to now: ");
location = Console.ReadLine();
}
}
}
}
}
so I'm writing a program that takes in a text line by line and then is supposed to output yes or no if the line contains the word problem.
The program is working, but I have to press enter twice to get the output.
The first enter I get, which is for the last line. And the second enter is so the while loop can break out.
Any suggestions to how I can improve this and not need the second enter?
using System;
using System.Collections.Generic;
namespace Tester
{
internal class Program
{
private static void Main(string[] args)
{
List<string> stringList = new List<string>();
string input = "";
while ((input = Console.ReadLine()) != string.Empty)
{
var s = input.ToLower();
stringList.Add(s.Contains("problem") ? "yes" : "no");
}
foreach (var str in stringList)
Console.WriteLine(str);
Console.ReadKey();
}
}
}
Well, for the last output you will type something. That's when (input = Console.ReadLine()) != string.Empty kicks in and the condition will pass.
The loop will come back to this line and block until you give it new input. Then supposedly you just type enter and in that case the loop will just exist. This is expected behaviour.
I'm not sure what upsets you about this. If you reaaaally wanted to get rid of the second enter, maybe you can put some token in your line (line /q or whatever) and whenever that is found in your line you know that you should break out of the loop.
Alternatively you can count how many inputs you get and make sure you get exactly 10 or 20 or whatever. When that number is reached, the loop will exit after the last input is processed.
Welcome to SO. :)
You can safely get rid of the last ReadKey. Given that you're creating a console application, you would normally rut it... in a console - as such, consoles don't close themselves after a program is done running. It's different if you run a console application in Windows OUTSIDE of a console - in this case, Windows will open a temporary console, run the app, and then close the console.
Also, if you're using Visual Studio, you can make VS wait for you by using the "start without debug" option (Ctrl+F5). VS will then add a "press enter to close" on it's own, at the end, to prevent the window from closing too fast, allowing you to check your outputs / exceptions.
One simple solution could be to output the "yes" or "no" values per line, rather than all at once at the end of your app.
Another way (which would require a bit more coding) would be to read individual keys, rather than lines - then you could react to the user pressing Esc, for example, rather than relying on an empty string ("extra" enter press).
You can use string.IsNullOrEmpty() and ToUpper() method is in general more accurate than ToLower(). So i'd probably refactor your code to something like :
private static void Main(string[] args)
{
List<string> stringList = new List<string>();
string input = "";
while(!string.IsNullOrEmpty(input = Console.ReadLine()))
stringList.Add(input.ToUpper().Contains("PROBLEM") ? "yes" : "no");
foreach (var str in stringList)
Console.WriteLine(str);
Console.ReadKey();
}
By the way welcome to SO... ;)
ok,do you mean this
static void Main(string[] args)
{
string input = "";
input = Console.ReadLine();
while (input != string.Empty)
{
if (input.Contains("problem"))
{
Console.WriteLine("yes");
}
else
{
Console.WriteLine("no");
}
input = Console.ReadLine();
}
Console.ReadKey();
}
maybe I know your intention.But if you want to break the while(input!=string.Empty) you must press an empty line.
I am currently studying C# and am trying to prepare for next weeks lessons which will be the introduction of classes and methods. To that end i have attempted to build a class called MaxBox which is meant to be a general utility class that I can store some general functions in like 'Displaying a String' or 'Play Again'. I've built my main file (Program) and my class file (MaxBox) and lines #23, #28 and #59 return the same general error 'An object reference is required for the non-static field, method, or property 'program.MaxBox.DisplayStr(string)'. #57 returns a similar error 'An object reference is required for the non-static field, method, or property 'program.MaxBox.PlayAgain()'
I'm a total newb really, and i'm wrestling with objects, I've done some research to get myself this far but I don't understand the language enough yet to be able to understand what the resources I've read are saying I guess to solve this error. Help and guidance is greatly appreciated. I'm still in my first weeks and really I know nothing.
Program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; // needed for close
using System.Threading.Tasks;
namespace a020_Breakcase_MeaningOfNames_C
{
class Program
{
public void Play()
{
/*
* Conditionals - Use switch/Case statement too:
* Evaluate user data (name)
* Return meaning of name evaluated
* OR
* Return 'Name not found' error message
* Say goodbye
*/
MaxBox.DisplayStr("What's in a name? Let's find out!");
Console.Write("\n\n");
do
{
MaxBox.DisplayStr("Enter Name: ");
string uName = Console.ReadLine().ToLower();
switch (uName)
{
case "doyle":
Console.WriteLine("Doyle means descendant of Dubhghalle");
break;
case "fiona":
Console.WriteLine("Fiona is considered to be a Latinised form of the Gaelic word fionn, meaning \"white\", \"fair\".");
break;
case "hunter":
Console.WriteLine("Hunter means to search with purpose");
break;
case "liam":
Console.WriteLine("This name is a short form of the Irish name Uilliam (William) which is now use independently as a given name. As a Hebrew name, Liam means \"my people; I have a nation\".");
break;
case "max":
Console.WriteLine("Short for of Maximilian, Maxwell, and the various name using it as a first syllable.");
break;
case "portia":
Console.WriteLine("It is of Latin origin. Feminine form of a Roman clan name. Portia was used by Shakespeare as the name of a clever, determined young heroine in \"The Merchant of Venice\" who disguises herself as a lawyer to save her husband's life.");
break;
default:
Console.WriteLine("I'm sorry but I don't know the meaning of the name " + uName + ".");
break;
}
} while (MaxBox.PlayAgain());
MaxBox.DisplayStr("C#eers!");
}
static void Main(string[] args)
{
Program myProgram = new Program();
myProgram.Play();
Console.Read();
}
}
}
My Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace a020_Breakcase_MeaningOfNames_C
{
class MaxBox
{
/*
* MaxBox is my general functions class
* Contains
* DisplayStr() - Display the string given
* PlayAgain() - If True, runs program again
*/
public String uName;
public String command;
public void DisplayStr(String StrTxt)
{ Console.Write(StrTxt); }
public Boolean PlayAgain()
{
Console.Write("\n\nDo you want to play again? (y)es or (n)o: ");
String command = Console.ReadLine().ToLower().Trim();
if (command == "y" || command == "yes") return true;
return false;
}
}
}
MaxBox's methods are not static, you need an instance of it.
MaxBox maxBox = new MaxBox();
at the beginning of your main class. Then
maxBox.DisplayStr(....)
also, just to get you thinking, you can replace:
if (command == "y" || command == "yes") return true;
return false;
with
return (command == "y" || command == "yes");
The methods PlayAgain and DisplayStr are instance methods on the type MaxBox. In order to call them you need an instance of MaxBox on which to call them. Right now you are trying to call them via the type name which only works for static methods
MaxBox.DisplayStr("hello world"); // wrong
MaxBox mb = new MaxBox();
mb.DisplayStr("hello world"); // right
It is possible to define methods such that you can invoke them from the type name. But doing so requires that they be marked as static
class MaxBox {
public static void DisplayStr2(string str){ ... }
}
MaxBox.DisplayStr2("hello world"); // right
I've recently written this short application in C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Checker
{
class Program
{
static void Main(string[] args)
{
Properties.Settings.Default.Save();
Program re = new Program();
re.next();
}
public void next()
{
Console.WriteLine("Have you already entered name?");
int ch = int.Parse(Console.ReadLine());
if (ch == 0)
{
Console.WriteLine("What is your name?");
String name = Console.ReadLine();
Console.WriteLine("Thank you!");
Console.ReadKey();
}
Console.WriteLine("Your name is " + name);
}
}
}
Now, I've created a settings file, and created a "name" variable there, with the "String" type.
The scope of it is "User".
So I want it to load the "name" variable with the properties line, but I can't even compile the program because of this error:
Error 1 The name 'name' does not exist in the current context
How can I solve it?
The answer to your problem becomes a little more apparent when you indent:
String name;
if (ch == 0)
{
Console.WriteLine("What is your name?");
name = Console.ReadLine();
Console.WriteLine("Thank you!");
Console.ReadKey();
}
else
{
name = Settings.Default.name;
}
Console.WriteLine("Your name is " + name);
Now you can see that you defined a String called name inside the if-block, thus using it in the Console.WriteLine outside the if-block is out of scope! Move that last Console.WriteLine inside the if-block to solve the scoping issue.
Edit: Based on your comment, your code needs a bit more logic to attain what you're trying to do. I updated my snippet above to accomplish what I think you're trying to do.
You declared that variable inside the if block.
As the compiler is trying to tell you, it doesn't exist outside that block.
If you want to use your Settings class, write Settings.Default.Name.
Your intentions are a bit unclear, but to me it seems as though you are trying to have the application display the name of the user if it has already been saved or ask for it if it hasn't. If that is the case, something like this should work:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Checker
{
class Program
{
static void Main(string[] args)
{
Program re = new Program();
re.next();
Properties.Settings.Default.Save();
}
public void next()
{
String name = Settings.Default.name;
if (String.IsNullOrEmpty(name))
{
Console.WriteLine("What is your name?");
name = Console.ReadLine();
Settings.Default.name = name;
Console.WriteLine("Thank you!");
Console.ReadKey();
}
else
{
Console.WriteLine("Your name is " + name);
}
}
}
}
In your OP, your settings were not being saved before the program exited nor were you setting the name property.