Finding the word in every line c# - c#

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.

Related

Loop either not working or never ending c#

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?

One time validation of user input to run application

I've made a WinForms application in C#.NET.
On first run I'm checking if 2 strings are equal, if its TRUE then the main form appears. However currently, this check is done whenever I start the program.
How can I pass this "validation result" to the computer so that every next run of the application, there will be no more checks needed?
One option is to store validation data in the registry. If the lines are equal, then create a branch in the registry and write the necessary data into it. Next, at the next start, we check for the presence of a branch and data in it. I attach a quick example.
string FisrtString = "Temp";
string SecondString = "Temp";
string SubBaseKeyString = #"SOFTWARE\ApplicationName";
RegistryKey vmsBaseKey = Registry.CurrentUser.OpenSubKey(SubBaseKeyString, true);
if (vmsBaseKey != null)
{
var Value = vmsBaseKey.GetValue("Validate");
if (Value != null)
{
if (Value.ToString() == "1")
{
//The user check passed here, you can open the window
}
}
else
{
//Here you must specify the action if the key is missing. Additional string comparison possible
}
}
else
{
if (FisrtString == SecondString)
{
//If the first line is equal to the second line, then assign a value
//The user check passed here, you can open the window
RegistryKey KEY_CREATE = Registry.CurrentUser.CreateSubKey(SubBaseKeyString);
KEY_CREATE.SetValue("Validate", "1");
KEY_CREATE.Close();
}
else
{
//If the first line is not equal to the second line, then we perform the desired action
}
}
You could save the result of your check into a config file and read it next time your program starts from the config file

While (true) problems, what did i do wrong?

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.

How to Alter behavior of a console application depending on Scheduled or Manual execution?

I have a simple console application, which is executed via Task Scheduler twice a day. When it runs like this, the default input for the Main() method will be the current month and current year.
However, sometimes this task needs to be executed manually outside the schedule; in such a case, it should prompt the user for Year and month separately.
I know how to send the arguments while executing the application like this:
myapplication.exe 2013 1
I can check for the number of arguments and code accordingly. But I want to prompt the user to enter month and year. How can we do this? Thank you for the help.
Please suggest a better title for this post.
You could introduce a special command line argument that would be only used when the app is executed via scheduler. If this argument is present, you would use current date, otherwise, you would prompt the user to enter the date for you.
E.g.
private static void Main(string[] args)
{
var yourFirstMagicNumber = -1;
var yourSecondMagicNumber = -1;
// Let's use the third argument as indicator that you need user input
if (args.Length > 2 && "true".Equals(args[2]))
{
Console.WriteLine("enter magic nr 1: ");
var firstArgument = Console.ReadLine();
yourFirstMagicNumber = Int32.Parse(firstArgument);
Console.WriteLine("enter magic nr 2: ");
var secondArgument = Console.ReadLine();
yourSecondMagicNumber = Int32.Parse(secondArgument);
}
else
{
yourFirstMagicNumber = Int32.Parse(args[0]);
yourSecondMagicNumber = Int32.Parse(args[1]);
}
}

C#: How do I add a response to "/?" in my program

Basically, I know that some apps when called in command line with "/?" spit back a formatted list of how to call the app with params from the command line. Also, these apps sometimes even popup a box alerting the user that the program can only be run with certain params passed in and give this detailed formatted params (similar to the command prompt output).
How do they do this (The /? is more important for me than the popup box)?
The Main method takes string[] parameter with the command line args.
You can also call the Environment.GetCommandLineArgs method.
You can then check whether the array contains "/?".
Try looking at NDesk.Options. It's a single source file embeddable C# library that provides argument parsing. You can parse your arguments quickly:
public static void Main(string[] args)
{
string data = null;
bool help = false;
int verbose = 0;
var p = new OptionSet () {
{ "file=", "The {FILE} to work on", v => data = v },
{ "v|verbose", "Prints out extra status messages", v => { ++verbose } },
{ "h|?|help", "Show this message and exit", v => help = v != null },
};
List<string> extra = p.Parse(args);
}
It can write out the help screen in a professional looking format easily as well:
if (help)
{
Console.WriteLine("Usage: {0} [OPTIONS]", EXECUTABLE_NAME);
Console.WriteLine("This is a sample program.");
Console.WriteLine();
Console.WriteLine("Options:");
p.WriteOptionDescriptions(Console.Out);
}
This gives output like so:
C:\>program.exe /?
Usage: program [OPTIONS]
This is a sample program.
Options:
-file, --file=FILE The FILE to work on
-v, -verbose Prints out extra status messages
-h, -?, --help Show this message and exit

Categories