I have a problem with calling a string from another method from the same script. I'm not sure if this is possible with C#
Sorry I'm new to C# but I used to do this in Objective-C so maybe its possible here?
So, the below code is the method I'm trying to use that string into.
This method checked if a message is passed in the game and execute the code.
void HandleMessage(string message, string metadata)
{
if (message == "UnlockName")
{
}
}
This is the method that contains the string needed (txt)
void OutputText( string txt ) {
//string firstName = lastLoadedLevel.contact.name.Split(new char[] { ' ' })[0];
//txt = txt.Replace("C:", firstName + ":");
txt = txt.Replace("D:", "D's name:");
txt = txt.Replace("[name]", PlayerPrefs.GetString("name"));
chat.AddText( txt, delegate {
options.gameObject.SetActive( true );
} );
}
Right now it contains (txt.Replace) which happens automaticlly throughout the text output.
I want to do the same in (void HandleMessage) to only do the replace code when the message "UnlockName" is passed.
The 2 commented lines here are what I need to use but I don't know how to use them in the first method.
Any help would be great :)
Thank you in advance.
Something like this maybe:
string HandleMessage(string message, string txt)
{
if (message == "UnlockName")
{
string firstName = lastLoadedLevel.contact.name.Split(new char[] { ' ' })[0];
return txt.Replace("C:", firstName + ":");
}
}
void OutputText(string txt, string message)
{
txt = HandleMessage(message, txt);
txt = txt.Replace("D:", "D's name:");
txt = txt.Replace("[name]", PlayerPrefs.GetString("name"));
chat.AddText(txt, delegate
{
options.gameObject.SetActive(true);
});
}
Might need some tweaking, I made some guesses on how you might be using things.
If nothing else, it should give you the concept of one way to pass strings in and back out of a method. You could also keep the void signature and pass in the string to be manipulated as a ref parameter.
Related
I write codes to receive the path of a text file and store it in a string variable that I declare in public.
Then I want to know if the file exists or not by using
System.IO.File.Exists(pathoffile)
But it always returns false even though there is a file.
And then when I try to add the string path directly like this
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
The function
System.IO.File.Exists(pathoffile)
return true
I already check the receive path(string) that I read from the text file. By cutting off "\n" and "\r" and using trim() too.But it still returns false.
Have I missed something? What difference between these two?. I'm too new to this c#. I'm very bad at this sorry in advance.
Here are my codes
public string pathfromread, partnumber, pathfile, portname, partnofromserial,propertypathfile; //Declare Variables
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\Properties.txt";
public string pathoffile ;
public string backuppath ;
public string pdffolderpath ;
private void propertyget()
{
if (File.Exists(propertyfile))
{
StreamReader readpropertyfile = new StreamReader(propertyfile);
string readproperty;
while ((readproperty = readpropertyfile.ReadLine()) != null)
{
string[] propertyfromread = readproperty.Trim().Split('=');
if (propertyfromread.GetValue(0).ToString() == "pathoffile")
{
pathoffile = propertyfromread.GetValue(1).ToString();
pathoffile = pathoffile.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pathoffile, "path file");
}
else if ((propertyfromread.GetValue(0).ToString() == "backuppath"))
{
backuppath = propertyfromread.GetValue(1).ToString();
backuppath = backuppath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(backuppath);
}
else if ((propertyfromread.GetValue(0).ToString() == "pdffolderpath"))
{
pdffolderpath = propertyfromread.GetValue(1).ToString();
pdffolderpath = pdffolderpath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pdffolderpath);
}
else if ((propertyfromread.GetValue(0).ToString() == "portname"))
{
portname = propertyfromread.GetValue(1).ToString();
portname = portname.Replace("\n", "").Replace("\r", "");
MessageBox.Show(portname);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
propertyget();
dv = dt.DefaultView; //set dv index count to != 0 to prevent error from null input when click on remove button
if (System.IO.File.Exists(pathoffile))//Check if file exist or not
{
}
else
{
try
{
MessageBox.Show("Database Text File Missing. Please Select New File", "Database Text File Missing", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
OpenFileDialog regispath = new OpenFileDialog();
regispath.Title = "Select Database Text File (part_no_and_path_list.txt)";
regispath.Multiselect = false;
regispath.Filter = "Text file (*.txt)|*.txt";
regispath.RestoreDirectory = true;
regispath.ShowDialog();
pathfile = regispath.FileName;
File.Copy(pathfile, pathoffile);
}
catch
{
And this is my property text file
pathoffile=#"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
backuppath=#"C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt"
pdffolderpath=#"C:\Users\PFA Wongsawat\Downloads\"
portname=COM3
In this case the result always a messageBox showing "Database Text File Missing. Please Select New File"
Thank you and sorry for my bad English.
You don't put #" and " in the text file, you only put them in the code because that's how the c# compiler knows they're strings (and knows not to interpret slashes as an escape character)
Just make your text file look like:
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
I also recommend you use:
Split(new []{'='}, 2)
This will allow you to use = in your path, by making split return a maximum of 2 split values; any = that are legitimately in the path would be preserved
Actually I recommend you use one of the various built in settings mechanisms that c# has; we haven't needed to read and write our own configuration files for about 25 years
If you really do want to continue rolling your own you can reduce your code massively by using a dictionary
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class Settings{
private Dictionary<string,string> _conf = new Dictionary<string,string>();
public string PathOfFile {
get => _conf["pathoffile"];
}
public void ReadConfig(){
File.ReadAllLines("conf.txt").ToDictionary(
x => x.Split(new[]{'='},2)[0],
x => x.Split(new[]{'='},2)[1]
);
}
}
Yep, it's all you need. Every time you want to add another setting, add another property (like public string PathOfFile), add another love to the file and make sure the string in the property matches the line in the file
In other areas, please read up on c# naming conventions; PublicThingsAreNamedLikeThis, _privateLikeThis, localLikeThis, neverlikethis
Thank you I've already solved this problem
By remove "#" and '""' from path in the property text file like this.
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
backuppath=C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt
pdffolderpath=C:\Users\PFA Wongsawat\Downloads\
portname=COM3
The reason I can't see this because I debug the program by seeing the result in message box and it not match with the real one. Thank you.
I'm trying to build a custom commandline for my app, i have several basic commands, and i simply use bunch of "if" statements to check what the command is. currently it looks something like this
public void ExecuteCommand()
{
string input = ReadLine(); //gets last string from input
bool isDone = false; //need bool to check whether command was executed or no, by default false.
Match result = Regex.Match(input, #"([^\s]+)"); //to get command name
string commandName = result.Value.ToLower();
string value = Regex.Match(input, #"\s(.*)").Value; //to get its parameter. currently everything after ' ' space.
if (commandName == "close")
{
Close(); isDone = true;
}
//so commandline is separate window, and appendedForm is a main form. in which some functions are executed.
if (commandName == "exit")
{
appendedForm.Close();
}
if (commandName == "spoof")
{
appendedForm.Fn_Spoof();
isDone = true;
}
if(commandName == "spoofstop")
{
appendedForm.Fn_StopCapture();
isDone = true;
}
if(commandName == "scan")
{
appendedForm.Fn_Scan(); isDone = true;
}
if(commandName == "clear")
{
output.Text = "";
WriteLine("Console cleared. Cache is empty.");
//data_lines.Clear();
isDone = true;
}
...
}
So that's basically it. I have a mainForm, and commandline form. string input is typed into commandline, then I check the name of command and execute some function from mainForm.
My question is, what is the best way of implementing such kind of thing? I surely can just continue writing bunch of "if"s, but something tells me that it's not the best way to make it.
I've thought of creating class "Command"
public class Command
{
public string name;
public string description;
public bool hasParameter;
Command()
{
}
}
And storing all commands in some sort of array, but I am not sure how would I use this to call a function from mainForm.
Any ideas are welcome!
You could stuff all commands into a Dictionary<string, someDelegate>; if you can live with all commands having the same return type.
I have used string and set up a few commands.
I make use of the params keyword to avoid the ugly new object[] on each call.
You still need to cast the arguments, unless you can make them all one type. (Which may actually be not such a bad idea, as they all come from an input string..)
Here is an example:
public delegate string cmdDel(params object[] args);
Dictionary<string, cmdDel> cmd = new Dictionary<string, cmdDel>();
Add a few functions:
cmd.Add("clear", cmd_clear);
cmd.Add("exit", cmd_exit);
cmd.Add("add", cmd_add);
cmd.Add("log", cmd_log);
With these bodies:
public string cmd_clear(params object[] args)
{
return "cleared";
}
public string cmd_exit(params object[] args)
{
return "exit";
}
public string cmd_add(params object[] args)
{
return ((int)args[0] + (int)args[1]).ToString();
}
public string cmd_log(params object[] args)
{
StringBuilder log = new StringBuilder();
foreach (object a in args) log.Append(a.ToString() + " ");
return log.ToString();
}
And test:
Console.WriteLine(cmd["clear"]());
Console.WriteLine(cmd["add"]( 23, 42));
Console.WriteLine(cmd["log"]( 23, "+" + 42, "=", cmd["add"]( 23, 42) ));
Console.WriteLine(cmd["exit"]());
cleared
65
23 + 42 = 65
exit
Of course you still need to use (at least) as many lines for setup as you have commands. And also need to do a similar amount of error checking.
But the command processing part can get pretty simple.
Hello I have a console application that successfully runs input through an array containing Bad Words and if there is a bad word then it will output some text then quits the application. Now I want to see what I can do With DetectBW() Including assigning it to a string Although DetectBW() is a void type and it returns nothing so assigning it to a string isn't possible if it's written like this
EX.
string Name = DetectBW();
Here's my code for further explanation
namespace CleanApp
{
class Application
{
This region contains bad words. I wrote it in otherwise it says a whole list of bad words which wouldn't be good for obvious reason.
//profanityArray()
This region contains numbers 0-318 Including 318
//ProNumArray()
This is the Main method
#region//Main() Put everything thats finished in here to output it to Console Apllication.
static void Main(string[] args)
{
string[] Sarray = profanityArray();
int[] Iarray = ProNum();
// infinite loop that writes "Ask A question." then accepts a line of text from user (DetectBW())
while (true)
{
Console.WriteLine("Ask A question.");
DetectBW();
}
}
#endregion
This is the DetectBW() method it takes PlayerInput()string Method (Console.Readline) and runs it through the profanityArray and detects if PlayerInput() contains any of the bad words in profanityArray.
#region // DetectBW()
static void DetectBW()
{
string PI = PlayerInput();
string[] PIA = profanityArray();
foreach(int i in ProNum())
{
if(PI.ToLower().Contains(PIA[i]))
{
if (PI.ToLower().Contains(" "+PIA[i]+" "))
{
Console.WriteLine(PI + " contains a bad word(s)!");
Console.WriteLine("If you can't be polite then get off!!");
Environment.Exit(0);
break;
}
if (PI.ToLower().Contains(PIA[i]+" ")|| PI.ToLower().Contains(" " + PIA[i]))
{
Console.WriteLine(PI + " contains a bad word(s)!");
Console.WriteLine("If you can't be polite then get off!!");
Environment.Exit(0);
break;
}
}
}
}
#endregion
This region is PlayerInput() it is the string method I was talking about.
#region// PlayerInput()
static string PlayerInput()
{
string S = Console.ReadLine();
return S;
}
#endregion
This is where I plan to to take the DetectBW() run it and take the same playerInput() used in DetectBW() and assign it to a string var for later use.
static void App()
{
Console.WriteLine("What is you name?");
// This is where i need Help!!
}
}
}
So this is my question:
1.
I know that I can't assign a void to a string variable but is there a way to take the same playerInput() used in DetectBW(), so I know that there isn't any bad words in it, and assign it to a name string variable.
I am getting an error in my code "Primary Constructor Body Is Not Allowed", and can't seem to find a way to fix it. The error occurred because I created a new public method, I have also tried using private and protected methods, but the error was still present. There is someone else on here that asked the same question. The answer that the particular person got leads me to believe that it may be specific to OS X.
Here is my code:
string txt = WordBank ();
string[] words = Moduel.TextToArray("Text.txt");
string compWord = Moduel.Random (words);
Console.WriteLine ("I have chosen a random word, try to guess it one letter at a time");
}
public static void WordBank ();
{
string txt;
Console.WriteLine ("Would you like to " +
"(A) choose 4 letter words " +
"(B) choose 5 letter words " +
"(C) choose 6 letter words " +
"(E) choose 7 lette r words or more?" +
"(F) all words?");
string input = Console.ReadLine ();
if (input = "A")
txt = "4 Letter Words.txt";
else if (input = "B")
txt = "5 Letter Words.txt";
else if (input = "C")
txt = "6 Letter Words.txt";
else if (input = "E")
txt = "7 Letters or More.txt";
else if (input = "F")
txt = "All Words.txt";
else
{
Console.WriteLine("You haven't chosen a valid option, please try again");
Main();
}
return txt;
}
}
}
and here is a picture of the error.
Error Message.
Error is in
public static void WordBank ();
Just remove semicolon from this line
public static void WordBank ()
And your function returned a string value so change function's definition to
public static string WordBank ()
public static void WordBank (); Remove the trailing ; in this line. and also make the return type to string if you have to return a string from the function.
So your method signature will be like the following:
public static string WordBank ()
{
string txt;
//Rest of code comes here
return txt;
}
Currently you have ; after your method declaration:
public static void WordBank ();
{
// code in your method
}
Having semicolon after method declaration is effectively the same like having an empty method body, so in your case the code is the same as
public static void WordBank ()
{
}
{
// code in your method
}
which is incorrect.
In order to fix the issue remove the ; after the method name:
public static void WordBank ()
{
// code in your method
}
There are certainly number of errors in you code.
string txt = WordBank (); where as your function does not return
anything public static void WordBank (); its void.
your code to declare a function public static void WordBank (); is wrong since you need to remove the ; at the end.
inside the function you states return txt; which is not right until your function actually returns something
and thus your code should be
public static string WordBank()
{
return "SomeString"; // in your case txt
}
Thanks everyone for your fast responses, the semicolon was the issue (feel really stupid now :P).
This code is not valid:
private void Foo(string optionalString = string.Empty)
{
// do foo.
}
But this code is:
private void Foo(string optionalString = "")
{
// do foo.
}
Why? Because string.Empty is a readonly field, not a constant, and defaults for optional parameters must be a compile-time constant.
So, onto my question... (well, concern)
This is what i've had to do:
private const string emptyString = "";
private void Foo(string optionalString = emptyString)
{
// do foo.
if (!string.IsNullOrEmpty(optionalString))
// etc
}
How do you guys handle optional string parameters?
Why can they not make String.Empty a compile-time constant?
Ummm... what's wrong with string optionalParm = "" again? Why is that bad? Do you really think you need a symbolic constant for an empty string in this case? How about this then?
const int Zero = 0;
void SomeMethod(int optional = Zero) { }
Does that seem at all silly to you?
if you don't like "" value you can use default(string).
I played with it and it is allowed.
private static void foo(string param = default(string)) {
if (!string.IsNullOrEmpty(param)) // or param != default(string)
Console.WriteLine(param);
}
Code Analysis warning 1026 says not to use optional parameters. It's better style to use overload methods, like this:
private void Foo()
{
Foo(string.Empty);
}
private void Foo(string optionalString)
{
// do foo.
if (!string.IsNullOrEmpty(optionalString))
// etc
}
The best way to handle them is with:
private void Foo(string optionalString = "")
{
// do foo.
}
So you can't use String.Empty. Everyone recognizes "", but if I found optionalString = nullString I wouldn't be sure what to think. If nothing else, name the thing emptyString--it's not null!
I'm answering this question.
Why can they not make String.Empty a compile-time constant?
Here is the disassemble code via Reflector of String.cs in mscorlib.dll
public static readonly Empty;
static String()
{
Empty = "";
WhitespaceChars = new char[] {
'\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', '', '\u2028', '\u2029', ' ', ''
};
}
So in windows platform, string.Empty is exactly "". But do you know, Martian have a different definition for Empty and WhitespaceChars in their OS.
If you are willing to play lose and treat null, "", and whitespace characters to be the same, then you can default to null. This becomes very handy when user name and password are optional fields due to a possibility of trusted connection to a db. You could change this logic to reset strings to null and thus modify the assert and the if. The important part is having a consistent convention.
private void RunSql(string serverName, string databaseName, string userName = null, string password = null)
{
userName = Strip(userName);
password = Strip(password);
// The `MsTest` assert - works in both `Debug` and `Release` modes.
Assert.AreEqual<bool>(
userName == String.Empty,
password == String.Empty,
"User name and password should be either both empty or both non-empty!");
Assert.IsFalse(String.IsNullOrWhiteSpace(serverName));
Assert.IsFalse(String.IsNullOrWhiteSpace(databaseName));
var cmdBuilder = new StringBuilder();
cmdBuilder.AppendFormat("sqlcmd -E -S {0} -d {1} ", serverName, databaseName);
if (userName.Length > 0)
{
cmdBuilder.AppendFormat("-U {0} -P {1} ", userName, password);
}
// Complete the command string.
// Run the executable.
}
// Cannot think of a good name. Emptify? MakeNullIfEmpty?
private string Strip(string source)
{
if (String.IsNullOrWhiteSpace(source))
{
return String.Empty;
}
return source;
}