how to convert a string to a ushort - c#

I have researched all of the questions that match my query and tried their solutions however none appear to work for me so I am asking how I convert a string to a ushort I have this set up all ready
public static string vid
{
get { return "<vehicleid>"; }
}
I've tried to use this : short[] result = vid.Select(c => (ushort)c).ToArray();
but when I go to put the vid ushort into this bit
[RocketCommand("vehicle", "This command spawns you a vehicle!", "<vehicleid>", AllowedCaller.Player)]
public void ExecuteCommandVehicle(IRocketPlayer caller, string[] command)
{
UnturnedPlayer spawner = (UnturnedPlayer)caller;
spawner.GiveVehicle(vid);
}
I get the following error :
Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from 'string' to 'ushort' arena v by FridgeBlaster C:\Users\Jonathan\Documents\Visual Studio 2015\Projects\arena v by FridgeBlaster\arena v by FridgeBlaster\vehicle.cs 71 Active

What you're looking for is ushort.TryParse or ushort.Parse methods.
I would suggest using this piece of code :
ushort[] result = vid.Where(i => ushort.TryParse(i, out short s)).Select(ushort.Parse);
Or if you do not use latest C# version :
ushort[] result = vid.Where(i => { ushort r = 0; return ushort.TryParse(i, out r); }).Select(ushort.Parse);
Okay so the problem ( as what your error says ) is that your GiveVehicle method accepts ushort as an argument and you're putting string type in it. Try doing something like this :
ushort val = 0;
if(ushort.TryParse(vid, out val))
{
UnturnedPlayer spawner = (UnturnedPlayer)caller;
spawner.GiveVehicle(val);
}
Based on this source which is responsible for calling method marked with RocketCommand attribute. Your <"vehicleid"> is/should be stored in a command array on first place. So to get this out and convert use something like this :
if(command.Length > 0)
{
ushort val = 0;
if(!string.IsNullOrWhiteSpace(command[0]) && ushort.TryParse(command[0], out val))
{
UnturnedPlayer spawner = (UnturnedPlayer)caller;
spawner.GiveVehicle(val);
}
}

For a simple string to ushort conversion: UInt16.Parse(string)

Based on the line short[] result = vid.Select(c => (ushort)c).ToArray(); it looks like there might be multiple IDs in a single string (each character, I assume).
If that's the case, try something like this:
ushort[] result = vid.ToCharArray().Select(c => (ushort) c).ToArray();
If you've got several actual numbers in the string separated by a character (e.g. "13,15,18"), give this a shot:
ushort[] result = vid.Split(separator).Select(str => ushort.Parse(str)).ToArray();
For either of these options, make sure you include using directives for the System and System.Linq namespaces.
With discussion on this and other answers, it looks like command is the result of tokenizing "/vehicle <id>". In this case, the body of the ExecuteCommandVehicle(IRocketPlayer, string[]) method should be similar to this:
ushort result = 0;
if (ushort.TryParse(command[1], out result)) {
UnturnedPlayer spawner = caller as UnturnedPlayer;
caller?.GiveVehicle(result);
}

Either you want to convert the string to a short:
Int16.Parse(...)
or
Int16.TryParse(...)
or you want to convert char to short by first converting string to array of chars:
vid.ToCharArray[..]

Related

Using two parameters (string, int) to define a max number of specific characters in string output

I am not very experienced with C# and have got a task to develop a simple program that can take two parameters; one string and one integer. The string is to be returned, and the integer is supposed to define the max number of each specific character that is returned in the string, i.e.:
input: "aaabbbbc", "2" output: aabbc
input: "acc", "1" output: ac
I've tried looking at different collections like IEnumerator to help make the code easier to write, but as I'm not very experienced I can't sort out how to utilize them.
This is the code that I've written so far:
public static string TwoParameters()
{
Console.Write("Write some characters (i.e. 'cccaabbb'): ");
string myString = Console.ReadLine();
return myString;
Console.Write("Write a number - ");
int max = Convert.ToInt32(Console.Read());
}
public static void Counter(string myString, int max)
{
string myString = TwoParameters(myString);
foreach (char a in myString)
{
var occurences = myString.Count(x => x == 'a');
if (occurences > max)
max = occurences;
}
}
Errors I get when running:
CS0136: Local or parameter 'myString' cannot be declared in scope because of enclosing local scope.
CS1501: No overload for method 'TwoParameters' takes 1 arg.
CS1061: 'string' does not contain a definition for count.
CS0165: Use of unassigned local variable 'myString'.
CS7036: There is no argument given that corresponds to the required formal parameter 'myString' of 'Program.Counter(string, int)'
Any kind of pointers to what I'm doing wrong, suggestions to how I can improve my code and/or finish it up for the program to make the output will be hugely appreciated.
A string can be treated as an IEnumerable<char>. You can use LINQ to first group the characters then take only 2 from each group, eg :
var input="aaabbbbc";
var max=2;
var chars=input.GroupBy(c=>c)
.SelectMany(g=>g.Take(2))
.ToArray();
var result=new String(chars);
This produces
aabbc
This query groups the characters together with GroupBy and then takes only max from each group with Take. SelectMany flattens all the IEnumerable<char> returned from Take into a single IEnumerable<char> that can be used to create a string
This function would also respect the order within the string, so aabcabc, 2 would result into aabcbc:
static string ReturnMaxOccurences(string source, int count)
{
return source.Aggregate(new Accumulator(), (acc, c) =>
{
acc.Histogram.TryGetValue(c, out int charCount);
if (charCount < count)
acc.Result.Append(c);
acc.Histogram[c] = ++charCount;
return acc;
}, acc => acc.Result.ToString());
}
But you need also this little helper class:
public class Accumulator
{
public Dictionary<char, int> Histogram { get; } = new Dictionary<char, int>();
public StringBuilder Result { get; } = new StringBuilder();
}
This method iterates the whole string and save within a histogram the occurences of each character. If the value is lower than the desired max value it will be added to the result string, otherwise it simply steps over the character and continues with the next.
Pointers to what you are doing wrong:
you reset your given max to the counts in your string
you only handle "a"
your TwoParameters function has unreachable code
you try to declare a variable name again already providing it to the function as parameter
you do not build a string to output
Using Linq is probably somewhat overkill for your level of knowledge. This is a simpler Version of Oliver's answer - respecting order of letters as well:
public static void Main()
{
var input = "abbaaabcbcccd";
var max = 2;
// stores count of characters that we added already
var occurences = new Dictionary<char,int>();
var sb = new StringBuilder();
foreach (var c in input)
{
// add with a count of 0 if not yet encountered
if (!occurences.ContainsKey(c))
{
// if you want only "consecutive" letters not repeated over max:
// uncomment the following line that resets your dict - you might
// want to use a single integer and character instead in that case
// occurences.Clear(); // better use a single int-counter instead
occurences[c] = 0;
}
// add character if less then max occurences
if (occurences[c] < max)
{
sb.Append(c);
occurences[c]+=1;
}
}
Console.WriteLine(sb.ToString());
}
Output:
abbaccd

Print hexadecimal code from int into string

I need to save a string with the hexadecimal code of an int.
For example the hexadecimal value for the int 15 is xoooF.
My problem is that I have to save this code in a string like this:
int myint = myStringLength; //this value might change
string myIntExhCode = myint.convertThisIntoMyCode();
//and the string has to be exactly "/xoooF"
So in this question I have two problmes:
The first is how to automatically convert an int into the hexadecimal code like 15 = xoooF
The second is how to create a string containing \xoooF because any try of concatenating strings like this resulted into a \\xoooF and this is not correct since in output I need the string to be converted into the ascii code.
How can I achieve those two tasks?
Any help will be appreciated
Your question is quite vague. If you want hexadecimal format, but with 0 (digit zero) changed into o (small latin letter o) you can implement, say, an extension method (in order to keep your proposed code intact):
public static partial class IntExtensions {
public static string convertThisIntoMyCode(this int value) {
return "\\x" + value.ToString("X4").Replace('0', 'o'); // or "/x" + ...
}
}
...
int myint = myStringLength; //this value might change
string myIntExhCode = myint.convertThisIntoMyCode();
// Test output
Console.Write(myIntExhCode);
How about
int i = 15;
string result = "\\x" + i.ToString("X").PadLeft(4, 'o');

How to use C# static string with Nlua

I am using NLua for script interface with my application.
I want to send keyboard input from LUA language to my C# code.
I do with this C# code.
using (Lua lua = new Lua())
{
lua.LoadCLRPackage();
lua.RegisterFunction("keypressC", null, typeof(TestNLUA).GetMethod("keypressC"));
lua.RegisterFunction("keypressS", null, typeof(TestNLUA).GetMethod("keypressS"));
lua["Key"] = new SpecialKey();
}
public class SpecialKey
{
public static readonly char EnterC = '\uE007';
public static readonly string EnterS = Convert.ToString(EnterC);
}
public class TestNLUA
{
public static void keypressC(char key)
{
// key = 57351 => OK
}
public static void keypressS(string key)
{
char[] akey = key.ToCharArray();
// akey[0] = 63 = ? (question mark) => KO
}
}
And in LUA Script I do
keypressC(Key.EnterC)
keypressS(Key.EnterS)
In keypressC, Nlua passe value 57351 to key parameter. It's OK.
In keypressS, Nlua passe value "?" to key parameter. It's KO.
I have no idea why there is the character "?".
Looks like a marshaling error in NLua (i.e. LuaInterface)?
Can you help me?
This is a marshaling problem in nLua/LuaInterface.
It uses Marshal.StringToHGlobalAnsi to marshal a string from C# to Lua.
It uses Marshal.PtrToStringAnsi to marshal a string from Lua to C#.
If you round-trip your example string through these functions, you can see it reproduces your problem:
string test = "\uE007";
Console.WriteLine(test);
Console.WriteLine("{0}: {1}", test[0], (int) test[0]);
IntPtr ptr = Marshal.StringToHGlobalAnsi(test);
string roundTripped = Marshal.PtrToStringAnsi(ptr, test.Length);
Console.WriteLine(roundTripped);
Console.WriteLine("{0}: {1}", roundTripped[0], (int) roundTripped[0]);
Output:
?
?: 57351
?
?: 63
Your problem goes away if you change the the marshaling functions to use Uni instead of Ansi, but you'd need to build nLua/LuaInterface from source.

Having trouble converting string to int

In my program I have a treeView. In the section that I am working with, the node's displayNames are numerical integer values, but are displayed as strings. I have come to a point in my program where I need to convert and temporarily store these displayNames in an integer variable. I usually use Regex.Match() to do this with no problem, but in this scenario I am getting the compiler error: Cannot implicitly convert type 'string' to 'int'.
This is my code:
//This is the parent node as you may be able to see below
//The children of this node have DisplayNames that are integers
var node = Data.GetAllChildren(x => x.Children).Distinct().ToList().First(x => x.identify == 'B');
//Get # of children -- if children exist
if (node.Children.Count() > 0)
{
for (int i = 0; i < node.Children.Count(); i++)
{
//Error on this line!!**
IntValue = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
}
}
*NOTE: DisplayName.Value is a string
To get from string to int, use int.Parse(string), it returns the int represented by the passed string and throws if the input format is incorrect.
int.Parse(node.Children.ElementAt(i).DisplayName.Value)
You can also use int.TryParse if you don't want the throw. in that case you would use:
int parsedValue;
if (int.TryParse(node.Children.ElementAt(i).DisplayName.Value, out parsedValue))
{
///Do whatever with the int
}
The problem is becuase you're casting from Match to int in this call
IntValue = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
Try something like this:
Match m = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
int value = m.Matches[0] //You'll have to verify this line, I'm going from memory here.

send a String array as parameter to a function

I have a function in a class called Function, like below:
public int SearchedRecords(String [] recs)
{
int counter = 0;
String pat = "-----";
String[] records = recs;
foreach (String line in records)
{
if (line.Contains(pat) == true)
{
counter++;
}
}
return counter;
}
And I am calling this method from my main class this way:
String [] file = File.ReadAllLines("C:/Users.../results.txt");
int counter = Function.SearchedRecords( []file);
But I get an error saying:
;expected
What is wrong?
Another question: The function above is counting from a file all the lines with the pattern ----- in them (even if with more dashes, or if the line has some chars before or after the dashes). Am I right?
It's something like the patterns in Java so maybe there is an other way.
Can you enlighten me?
Remove the [] from your parameter.
e.g.
int counter = Function.SearchedRecords(file);
And yes, your assumption about the behavior of the Contains method is correct - you'll match any line containing five consecutive dashes, regardless of what characters are before or after them.
If you want to parse for exactly five dashes, with nothing before or after them I suggest looking into the RegEx class (regular expressions).
Change
int counter = Function.SearchedRecords( []file);
to
int counter = Function.SearchedRecords(file);
and yes, this will work, for that string.
However Contains is case sensitive, if you were matching on a name, or another string with alphabetic characters, the case would have to be identical to match e.g. line.Contains("Binary Worrier") will not match a string "Hello binary worrier".
Also, reading the entire file into memory is fine if you know that the file will always be small, this method gets less efficient the larger the file.
Better to always use something like System.IO.StreamReader or System.IO.File.ReadLines (available in .Net 4 and later), these allow you to consume the file one line at a time. e.g.
using (var reader = new System.IO.StreamReader("MyFile.txt"))
{
while(!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line.Contains(pattern))
counter++;
}
}
Change it to
int counter = Function.SearchedRecords(file);
Remove '[]' from a method call. Yes, your function seems to count what you want.
First of all you need to create an instance of function class and then run the function. Hope following code helps
Function fb = new Function();
int counter = fb.SearchedRecords(file);
Right now, you are using SearchRecords as an static function of a static class which doesn't require instantiation.
You can do this in a shorter way using LINQ:
int counter = file.Count(line => line.Contains("-----"));

Categories

Resources