Keep getting the error message does not contain a static main method for suitable entry point. Would anyone be able to explain this error to me and possibly help me fix it? Thanks. New to C#
{
class Authenticator
{
private Dictionary<string, string> dictionary = new Dictionary<string, string>();
public void IntialValues()
{
dictionary.Add("username1", "password1");
dictionary.Add("username2", "password2");
dictionary.Add("username3", "password3");
dictionary.Add("username4", "password4");
dictionary.Add("username5", "password5");
}
public bool Authenticate(Boolean authenticated)
{
Console.WriteLine("Please enter a username");
string inputUsername = Console.ReadLine();
Console.WriteLine("Please enter your password");
string inputPassword = Console.ReadLine();
if (dictionary.ContainsKey(inputUsername) && dictionary[inputUsername] == inputPassword)
{
authenticated = true;
}
else
{
authenticated = false;
}
return authenticated;
}
}
}
If all of your code consists only of the block shown above then the error is more than clear. A Main method is required in your program.
The Main method is, by convention, the default point where the code starts executing. You can get here a more in depth explanation
So, for example, you need to add the following code
class Authenticator
{
static void Main(string[] args)
{
Authenticator au = new Authenticator();
au.InitialValues();
if(au.Authenticate())
Console.WriteLine("Authenticated");
else
Console.WriteLine("NOT Authenticated");
Console.WriteLine("Press Enter to end");
Console.ReadLine();
}
// Move the boolen variable inside the method
public bool Authenticate()
{
bool authenticated = false;
Console.WriteLine("Please enter a username");
string inputUsername = Console.ReadLine();
Console.WriteLine("Please enter your password");
string inputPassword = Console.ReadLine();
if (dictionary.ContainsKey(inputUsername) && dictionary[inputUsername] == inputPassword)
{
authenticated = true;
}
else
{
authenticated = false;
}
return authenticated;
}
}
By the way, you should remove the parameter passed in input to the Authenticate method. You should declare it as an internal variable, set it depending on the outcome of the check and return it.
However, you could remove that variable altogether writing
....
return (dictionary.ContainsKey(inputUsername)) &&
(dictionary[inputUsername] == inputPassword)
}
All executable programs must have a Main function somewhere in the project that is compiled to the exe.
If you just want to compile a class (eg to a dll) then you have to set that as the "project type" in visual studio.
The easiest way is to create a new project, but select class library as project type, and then paste your code in there. Alternatively you can use the command line to compile a file to a dll like so:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:library Authenticator.cs
Related
This question already has answers here:
Use a variable from another method in C#
(2 answers)
Closed 1 year ago.
Hey I'm very very new to c# coding and OOP, I'm currently working on a system that allows users to create login details, and then login with said details, however when I get to the part where I verify the users details I am having issues getting it to recognize my object, AccName, credentialCheck() can't successfully get the information from accountCreation(), I know this is a very basic thing to know but I have tried so many things and none of them have worked, or I haven't been doing them properly. My code is shown below and any guidance that could be provided would be greatly appreciated.
static void accountCreation()
{
Console.Write("Username: ");
string userNameInput = Console.ReadLine();
Console.Write("Email: ");
string userEmailInput = Console.ReadLine();
Console.Write("Password: ");
string userPasswordInput = Console.ReadLine();
Account AccName = new Account($"{userNameInput}", $"{userEmailInput}", $"{userPasswordInput}");
Console.Write($"{userNameInput} Registered successfully");
Console.WriteLine();
}
static void credentialCheck()
{
Console.Write("Email: ");
string userEmailCheck = Console.ReadLine();
Console.Write("Password: ");
string userPasswordCheck = Console.ReadLine();
if (userEmailCheck == AccName.userEmail )
{
Console.WriteLine();
Console.WriteLine("Success");
}
I suppose you are calling credentialCheck() just after accountCreation() and in the same thread. That out of the way, I supposed you have accName as a static variable and your class overall looks like this:
class Login {
protected static Account accName;
static void accountCreation()
{
// ...
accName = new Account(userNameInput, userEmailInput, userPasswordInput);
}
}
This means the variable accName remains as far as the execution context is concerned and not immediately destroyed after accountCreation() returns.
I want to make a function that reads the console for a key, check it's validity and then return.
This is my solution but it doesn't work, why?
public static int KeySupplier()
{
string keyString;
Console.WriteLine("Please provide a valid cipher key");
keyString = Console.ReadLine();
if(int.TryParse(keyString, out int key) == true)
{
return key;
}
else
{
Console.WriteLine("Invalid key!");
KeySupplier();
}
}
In order for this code to compile, all paths where the function exits must return an int. The simplest way to solve this is to change your code so that it reads:
public static int KeySupplier()
{
string keyString;
Console.WriteLine("Please provide a valid cipher key");
keyString = Console.ReadLine();
if(int.TryParse(keyString, out int key) == true)
{
return key;
}
else
{
Console.WriteLine("Invalid key!");
return KeySupplier(); // 'return' added here
}
}
That said, what you've written is perhaps not the best way to solve the problem as you may encounter a StackOverflowException. If someone who was running this code was to simply keep pressing a non-numerical letter you'd end up in many, many nested calls to KeySupplier which could eventually throw an exception.
Another way to implement this, assuming that the intent of the code is to simply return any string that parses as an int would be to use a while loop:
public static int KeySupplier()
{
while (true)
{
Console.WriteLine("Please provide a valid cipher key");
var keyString = Console.ReadLine();
if (int.TryParse(keyString, out int key))
{
return key;
}
Console.WriteLine("Invalid key!");
}
}
When this method is called, it sits in the while loop until a string that can be parsed as an int is entered by the user, at which point the method returns it to the calling code.
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();
}
}
}
}
}
I am writing a short program. What I need is that I want to set "correct" parameter in Game.cs, and in my advTry.cs, I want to use this "correct" parameter to determine the output. with my class advTry.cs like:
public bool correct { get; set; }
if (correct)
{
solveButton = new MenuButton(contentManager.Load<Texture2D>("solve"),
buttonCenter, GameState.AnswerNo);
Console.WriteLine("OK");
}
else
{
solveButton2 = new MenuButton(contentManager.Load<Texture2D>("solve"),
buttonCenter, GameState.AnswerYes);
Console.WriteLine("Not OK");
}
While in my GAME.cs, I define correct as:
if (messageString == "18")
{
Console.WriteLine("Main OK");
advTry.correct = true;
}
else
{
advTry.correct = false;
Console.WriteLine("Main not OK");
}
I use the Console.WriteLine to check the passing of boolean parameter "correct". While the result is originally "Not OK", then when I start to input "18", it gives out"Main not OK" first, then "Main OK" (easy to understand, because input"1" then "8").
However, the biggest problem is "OK" never comes out, the state "GameState.AnswerNo" can't be fulfilled, Why is that please? How to fix it please?
Your question is not at all clear. You haven't given any idea of the structure of the code apart from those two conditionals. It's just impossible to answer right now. However, my best guess from what you've written here is that you've set the value of "correct" to true in your advTry class, but you haven't run the code inside that class to output OK to the console. That code won't run automatically just because you set the value of "correct". You need to do something like this in advTry.cs:
private bool _correct;
public bool correct
{
get { return _correct; }
set
{
_correct = value;
output();
}
}
private void output
{
if (_correct)
{
//output "OK"
}
else
{
//output "Not OK"
}
}
Consider this small program:
class Program
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("Please copy something into the clipboard.");
WaitForClipboardChange();
Console.WriteLine("You copied " + Clipboard.GetText());
Console.ReadKey();
}
static void WaitForClipboardChange()
{
Clipboard.SetText("xxPlaceholderxx");
while (Clipboard.GetText() == "xxPlaceholderxx" &&
Clipboard.GetText().Trim() != "")
Thread.Sleep(90);
}
}
I run it, and I copy a string from Notepad. But the program just gets an empty string from the clipboard and writes "You copied ".
What's the problem here? Is there something that makes clipboard access behave weirdly in a console application?
This is Windows 7 SP1 x86, .NET 4 Client Profile.
Use this function
static string GetMeText()
{
string res = "starting value";
Thread staThread = new Thread(x =>
{
try
{
res = Clipboard.GetText();
}
catch (Exception ex)
{
res = ex.Message;
}
});
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();
return res;
}
In this line:
Console.WriteLine("You copied " + Clipboard.GetMeText());
The problem is that the clipboard only works with certain threading models (ApartmentState.STA) so you have to make a new thread and give it that model this code does that.
I can reproduce the problem with your code on .NET 4 Client Profile, but when I switch to .NET 4 or 4.5 it works as expected.
However, the ClipBoard.GetText() manual states:
Use the ContainsText method to determine whether the Clipboard contains text data before retrieving it with this method.
I take that as an instruction, not a suggestion, so, try this:
class Program
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("Please copy something into the clipboard.");
WaitForClipboardChange();
Console.WriteLine("You copied " + Clipboard.GetText());
Console.ReadKey();
}
static void WaitForClipboardChange()
{
Clipboard.Clear();
while (!Clipboard.ContainsText())
Thread.Sleep(90);
}
}
It does show the copied text, although I must say this lets my system hang horribly when I copy some text.
This works for me:
static void Main(string[] args)
{
Console.WriteLine("Please copy something into the clipboard.");
string text = WaitForClipboardChange();
Console.WriteLine("You copied " + text);
}
static string WaitForClipboardChange()
{
string placeholderText = "xxPlaceholderxx";
Clipboard.SetText(placeholderText);
string text = null;
do
{
Thread.Sleep(90);
text = Clipboard.GetText();
}
while (string.IsNullOrWhiteSpace(text) || text.Equals(placeholderText));
return text;
}
Your current code explicitly waits for first change from "xxPlaceholderxx" to anything (your condition is "not particular string AND not empty" which turns false as soon as string changes from "xxPlaceholderxx" to anything, including ""):
while (Clipboard.GetText() == "xxPlaceholderxx"
&& Clipboard.GetText().Trim() != "")
You probably want || (or) instead of and:
// assuming System.Windows.Forms.Clipboard
static void WaitForClipboardChange()
{
Clipboard.SetText("xxPlaceholderxx");
while (Clipboard.GetText() == "xxPlaceholderxx"
|| string.IsNullOrWhiteSpace(Clipboard.GetText()))
Thread.Sleep(90);
}