So I want to make "hello world!" in a creative way and I came up with and idea to use ASCII but I don't realy now how to convert from char to ASCII symbol (neither from string). Here is my code:
public static void Main()
{
List<string> imie = new List<string>();
greet();
}
public static string greet()
{
string s = "";
string nums = "104 101 108 108 111 32 119 111 114 108 100 33";
char[] numbers = nums.ToCharArray();
foreach (char l in numbers)
{
s += Encoding.ASCII.GetChars(new byte[] {l});
}
return s;
}
Also in line "s += Encoding.ASCII.GetChars(new byte[] {l});" I am getting error "Cannot implicitly convert type 'char' to 'byte'. An explicit conversion exists (are you missing a cast?)"
here you go
public static string greet() {
string s = "";
string nums = "104 101 108 108 111 32 119 111 114 108 100 33";
var numbers = nums.Split(" ");
foreach (var nstr in numbers) {
int k = Int32.Parse(nstr);
s += Convert.ToChar(k);
}
return s;
}
or better (appending to a string is very ineffiecint)
public static string greet() {
StringBuilder s = "";
string nums = "104 101 108 108 111 32 119 111 114 108 100 33";
var numbers = nums.Split(" ");
foreach (var nstr in numbers) {
int k = Int32.Parse(nstr);
s.Append(Convert.ToChar(k));
}
return s.ToString();
}
public static string greet()
{
string nums = "104 101 108 108 111 32 119 111 114 108 100 33";
var bytes = nums.Split().Select(n => byte.Parse(n)).ToArray();
return Encoding.ASCII.GetChars(bytes);
}
Quite creative, but it seems that the level of creativity does not match the level of your C# knowledge yet... There are many misunderstandings, which makes answering this question a bit hard.
Let's start in the Main() method:
you don't use the variable
List<string> imie = new List<string>();
but actually, that type of list would be useful in a different place of the program. For the moment, let's put this line of code inside the greet() method instead.
you call greet() which returns a string, but you never use the return value. Let's surround this by a print statement:
Console.WriteLine(greet());
The Main() method now looks like
public static void Main()
{
Console.WriteLine(greet());
}
Let's go on with the greet() method.
the variable s is not very descriptive. Let's rename it to helloworld, so you have a better idea of what it's being used for.
Instead of using a single string, let's take the idea of having a list of strings instead.
List<string> numbers = new List<string>{"104", "101", "108", "108", "111", "32", "119", "111", "114", "108", "100", "33"};
We can now get rid of nums and the old numbers variables. We don't need those.
The for loop gives you a string instead of single characters (which would have been individual digits of the numbers actually). Let's also change the variable name.
foreach (string number in numbers)
It's good practice to have singular and plural in for loops.
For the string concatenation, let's use int.Parse() instead of further messing with individual digits of a character. In order for the number to become a character, we need to cast it to a char
helloworld += (char) int.Parse(number);
The method:
public static string greet()
{
List<string> numbers = new List<string>{"104", "101", "108", "108", "111", "32", "119", "111", "114", "108", "100", "33"};
string helloworld = "";
foreach (string number in numbers)
{
helloworld += (char) int.Parse(number);
}
return helloworld;
}
Related
I have a text file that include of numbers and I save it in a string array.
one line of my text file is this:
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21
every line save in one of indexes of string array.
now how can i access array elements as int type and search and calculate in all of array?
this is my array:
string [] lines = File.ReadAllLines(txtPath.Text);
for example I want to return indexes of array that include number'14' in all of array .
This is the easiest and clearest way to solve it. I commented so you can better understand what happens in the entire program.
class Program
{
static void Main(string[] args)
{
// this is your array of strings (lines)
string[] lines = new string[1] {
"2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21"
};
// this dictionary contains the line index and the list of indexes containing number 14
// in that line
Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
// iterating over lines array
for (int i = 0; i < lines.Length; i++)
{
// creating the list of indexes and the dictionary key
List<int> indexes = new List<int>();
dict.Add(i, indexes);
// splitting the line by space to get numbers
string[] lineElements = lines[i].Split(' ');
// iterating over line elements
for (int j = 0; j < lineElements.Length; j++)
{
int integerNumber;
// checking if the string lineElements[j] is a number (because there also this case 114:275:5)
if (int.TryParse(lineElements[j], out integerNumber))
{
// if it is we check if the number is 14, in that case we add that index to the indexes list
if (integerNumber == 14)
{
indexes.Add(j);
}
}
}
}
// Printing out lines and indexes:
foreach (int key in dict.Keys)
{
Console.WriteLine(string.Format("LINE KEY: {0}", key));
foreach (int index in dict[key])
{
Console.WriteLine(string.Format("INDEX ELEMENT: {0}", index));
}
Console.WriteLine("------------------");
}
Console.ReadLine();
}
}
UPDATE 1:
As you requested:
special thanks for your clear answering.if i want to do search for all of my array elements what can i do? it means instead of only
number'14' i want to print indexes of all numbers that appear in
indexes
If you want to print all the indexes you should Console.WriteLine(j), that is the index of the inner for cycle, instead of checking the number value if (integerNumber == 14).
So, this is the program:
class Program
{
static void Main(string[] args)
{
// this is your array of strings (lines)
string[] lines = new string[1] {
"2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21"
};
// this dictionary contains the line index and the list of indexes containing number 14
// in that line
Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
// iterating over lines array
for (int i = 0; i < lines.Length; i++)
{
// creating the list of indexes and the dictionary key
List<int> indexes = new List<int>();
dict.Add(i, indexes);
// splitting the line by space to get numbers
string[] lineElements = lines[i].Split(' ');
// iterating over line elements
for (int j = 0; j < lineElements.Length; j++)
{
// printing all indexes of the current line
Console.WriteLine(string.Format("Element index: {0}", j));
}
}
Console.ReadLine();
}
}
UPDATE 2:
As you requested:
if i want to search my line till first " : " apper and then search next line, what can i do?
You need to break the for cycle when you are on the element with :
class Program
{
static void Main(string[] args)
{
// this is your array of strings (lines)
string[] lines = new string[1] {
"2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114:275:5 8 1 14 10 6 10 18 12 25 7 40 1 30 18 8 2 1 5 21 10 2 21"
};
// this dictionary contains the line index and the list of indexes containing number 14
// in that line
Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();
// iterating over lines array
for (int i = 0; i < lines.Length; i++)
{
// creating the list of indexes and the dictionary key
List<int> indexes = new List<int>();
dict.Add(i, indexes);
// splitting the line by space to get numbers
string[] lineElements = lines[i].Split(' ');
// iterating over line elements
for (int j = 0; j < lineElements.Length; j++)
{
// I'm saving the content of lineElements[j] as a string
string element = lineElements[j];
// I'm checking if the element saved as string contains the string ":"
if (element.Contains(":"))
{
// If it does, I'm breaking the cycle, and I'll continue with the next line
break;
}
int integerNumber;
// checking if the string lineElements[j] is a number (because there also this case 114:275:5)
if (int.TryParse(lineElements[j], out integerNumber))
{
// if it is we check if the number is 14, in that case we add that index to the indexes list
if (integerNumber == 14)
{
indexes.Add(j);
}
}
}
}
// Printing out lines and indexes:
foreach (int key in dict.Keys)
{
Console.WriteLine(string.Format("LINE KEY: {0}", key));
foreach (int index in dict[key])
{
Console.WriteLine(string.Format("INDEX ELEMENT: {0}", index));
}
Console.WriteLine("------------------");
}
Console.ReadLine();
}
}
As you can see, if you run this piece of code and compare it with the first version, in output you'll get only the index of the first 14 occurrence, because the second one is after the string with :.
First you must get all conttent of file in the string array format:
public string[] readAllInFile(string filepath){
var lines = File.ReadAllLines(path);
var fileContent = string.Join(' ',lines);//join all lines of file content in one variable
return fileContent.Split(' ');//each word(in your case each number) in one index of array
}
and in usage time you can do like this:
var MyFileContent = readAllInFile(txtPath.Text);
int x= Convert.ToInt32(MyFileContent[2]);
IEnumerable<int> numbers = MyFileContent.Select(m=> int.Parse(m);)
var sumeOf = numbers.sum();
you can use linq to have more tools on collections.
var linesAsInts = lines.Select(x => x.Split(' ').Select(int.Parse));
var filteredLines = linesAsInts.Where(x => x.Contains(14));
// define value delimiters.
var splitChars = new char[] { ' ', ':' };
// read lines and parse into enumerable of enumerable of ints.
var lines = File.ReadAllLines(txtPath.Text)
.Select(x => x.Split(splitChars)
.Select(int.Parse));
// search in array.
var occurences = lines
.Select((line,lineIndex) => line
.Select((integer, integerIndex) => new { integer, integerIndex })
.Where(x => x.integer == 10)
.Select(x => x.integerIndex));
// calculate all of array.
var total = lines.Sum(line => line.Sum());
I have a array of strings having values
string[] words = {"0B", "00", " 00", "00", "00", "07", "3F", "14", "1D"};
I need it to convert into array of ulong
ulong[] words1;
How should I do it in c#
I think I should add some background.
The data in the string is coming from textbox and I need to write the content of this textbox in the hexUpDown.Value parameter.
var ulongs = words.Select(x => ulong.Parse(x, NumberStyles.HexNumber)).ToArray();
If you need to combine the bytes into 64 bit values then try this (assumes correct endieness).
string[] words = { "0B", "00", " 00", "00", "00", "07", "3F", "14", "1D" };
var words64 = new List<string>();
int wc = 0;
var s = string.Empty;
var results = new List<ulong>();
// Concat string to make 64 bit words
foreach (var word in words)
{
// remove extra whitespace
s += word.Trim();
wc++;
// Added the word when it's 64 bits
if (wc % 4 == 0)
{
words64.Add(s);
wc = 0;
s = string.Empty;
}
}
// If there are any leftover bits, append those
if (!string.IsNullOrEmpty(s))
{
words64.Add(s);
}
// Now attempt to convert each string to a ulong
foreach (var word in words64)
{
ulong r;
if (ulong.TryParse(word,
System.Globalization.NumberStyles.AllowHexSpecifier,
System.Globalization.CultureInfo.InvariantCulture,
out r))
{
results.Add(r);
}
}
Results:
List<ulong>(3) { 184549376, 474900, 29 }
How to set space between TextBox values into array?
TextBox values:
1 32 54 76 89 89 454 23
Expected output array:
value[1]=1;
value[2]=32;
value[3]=76
...
Try this:
var numbers = textBox1.Text.Split(' ');
List<int> lst = numbers.Select(item => int.Parse(item)).ToList();
It will be even better if you use method group like this:
List<int> lst = numbers.Select(int.Parse).ToList();
Then you can get it's values like this:
lst[0] --> 1
lst[1] --> 32
and ...
You first have to split the users input:
var values = myTextBox.Text.Split(' ');
Now you can easily set your array of integers:
var myArr = values.Select(x => Convert.ToInt32(x)).ToArray();
Alternativly you can also use Int.Parse instead of Convert.ToInt32.
String[] values = tv.Text.Split(' '); // the values as string
int[] arr = new int[values.Length]; // the values as integer
for (int i = 0; i < arr.Length; i++)
arr[i] = int.Parse(values[i]);
If I understand you correct you need to create int array from string you can do it like this:
string TextBoxText = "1 32 54 76 89 89 454 23";
var value = TextBoxText.Split(' ').Select(Int32.Parse).ToList();
Then you can use your array like this:
Console.WriteLine(value[1]);
Console.WriteLine(value[2]);
TextBoxText should be Text property of your TextBox component.
I need help to split a collection of strings that have rather strange pattern.
Example data:
List<string> input = new List<string>();
input.Add("Blue Code \n 03 ID \n 05 Example \n Sky is blue");
input.Add("Green Code\n 01 ID\n 15");
input.Add("Test TestCode \n 99 \n Testing is fun");
Expected output:
For input[0]:
string part1 = "Blue"
string part2 = "Code \n 03"
string part3 = "ID \n 05"
string part4 = "Example \n Sky is blue"
For input[1]:
string part1 = "Green"
string part2 = "Code\n 01"
string part3 = "ID\n 15"
For input[2]:
string part1 = "Test"
string part2 = "TestCode \n 99"
string part3 = "\n Testing is fun"
Edited with one more example:
"038 038\n 0004 049.0\n 0006"
Expected output:
"038"
"038\n 0004"
"049.0\n 0006"
In short, I don't even know how to describe the pattern... It seems like I need the first string(act as a key) right before the "\n" as part of the new string, but the last input[2] has slightly different pattern from the other 2. Also, please take note of the spaces, they are extremely inconsistent.
I know this is a long shot, but please let me know if anyone can figure out how to deal with these data.
Updated: I think I can forget about solving this... When I actually take a look at the database in detail, I just found out that there are NOT only \n, it can be... anything, including |a |b |c (from a-z, A-Z), \a \b \c (from a-z, A-Z). Manually re-entering the data could be much more easier...
I would say the pattern is:
List<string> input = new List<string>();
input.Add("Blue Code \n 03 ID \n 05 Example \n Sky is blue");
input.Add("Green Code\n 01 ID\n 15");
input.Add("Test TestCode \n 99 \n Testing is fun");
foreach(string text in input)
{
string rest = text;
//1 Take first word
string part1 = rest.Split(' ')[0];
rest = rest.Skip(part1.Length).ToString();
//while rest contains (/n number)
while (rest.Contains("\n"))
{
//Take until /n number
int index = rest.IndexOf("\n");
string partNa = rest.Take(index).ToString();
string temp = rest.Skip(index).ToString();
string partNb = temp.Split(' ')[0];
int n;
if (int.TryParse("123", out n))
{
string partN = partNa + partNb;
rest = rest.Skip(partN.Length).ToString();
}
}
//Take rest
string part3 = rest;
}
It could probably be written a bit more optimised, but you get the idea.
Ok, I have got this little code snippet to generate the output you are looking for. the Pattern seems to be: Word [Key \n Value] [Key \n Value] [Key \n Value (With Spaces)]
Where the Key can be empty. Is that right?
var input = new List<string>
{
"Blue Code \n 03 ID \n 05 Example \n Sky is blue",
"Green Code\n 01 ID\n 15",
"038 038\n 0004 049.0\n 0006",
"Test TestCode \n 99 \n Testing is fun"
};
var output = new List<List<string>>();
foreach (var item in input)
{
var items = new List<string> {item.Split(' ')[0]};
const string strRegex = #"(?<group>[a-zA-Z0-9\.]*\s*\n\s*[a-zA-Z0-9\.]*)";
var myRegex = new Regex(strRegex, RegexOptions.None);
var matchCollection = myRegex.Matches(item.Remove(0, item.Split(' ')[0].Length));
for (var i = 0; i < 2; i++)
{
if (matchCollection[i].Success)
{
items.Add(matchCollection[i].Value);
}
}
var index = item.IndexOf(items.Last()) + items.Last().Length;
var final = item.Substring(index);
if (final.Contains("\n"))
{
items.Add(final);
}
else
{
items[items.Count -1 ] = items[items.Count - 1] + final;
}
output.Add(items);
}
I need to parse a line that is in a similar format as following:
s = "Jun 21 09:47:50 ez-x5 user.debug if_comm: [TX] 02 30 20 0f 30 31 39 24 64 31 30 31 03 54 ";
I am splitting the line with [TX] or [RX]. Here's what I do with the parsed string:
s = "Jun 21 09:47:50 ez-x5 user.debug if_comm: [TX] 02 30 20 0f 30 31 39 24 64 31 30 31 03 54 ";
string[] stringSeparators = new string[] { "[TX] " + start_key };
string transfer = s.Split(stringSeparators, 2, StringSplitOptions.None)[1];
//At this point, transfer[] = 02 30 20 0f 30 31 39 24 64 31 30 31 03 54
if (!string.IsNullOrEmpty(transfer))
{
string key = "";
string[] split = transfer.Split(' ');
if (split[0] == start_key)
{
for (int i = 0; i < key_length; i++)
{
key += split[i + Convert.ToInt32(key_index)];
}
TX_Handle(key);
}
}
stringSeparators = new string[] { "[RX]" + start_key };
transfer = s.Split(stringSeparators, 2, StringSplitOptions.None)[1];
if (!string.IsNullOrEmpty(transfer))
{
string key = "";
string[] split = transfer.Split(' ');
if (split[0] == start_key)
{
for (int i = 0; i < key_length; i++)
{
key += split[i + Convert.ToInt32(key_index)];
}
RX_Handle(key);
}
}
Basically, because I have no realistic way of comparing whether the given token is [TX] or [RX], I am forced to use the above approach to separate the string, which requires me to write essentially the same code twice.
What is a way I can get around this problem and know which token is being parsed so that I don't have to duplicate my code?
The best way to do this is look at what is common. What is common in your code? Splitting based on 2 different tokens and a function call based on 2 different tokens. This can be broken into a conditional, so, why not move the common element into a conditional?
const string receiveToken = "[RX] ";
const string transmitToken = "[TX] ";
string token = s.IndexOf(receiveToken) > -1 ? receiveToken : transmitToken;
..now you have your token, so you can remove most of the duplication.
stringSeparators = new string[] { token + start_key };
transfer = s.Split(stringSeparators, 2, StringSplitOptions.None)[1];
if (!string.IsNullOrEmpty(transfer))
{
string key = "";
string[] split = transfer.Split(' ');
if (split[0] == start_key)
{
for (int i = 0; i < key_length; i++)
{
key += split[i + Convert.ToInt32(key_index)];
}
RX_TX_Handle(key, token);
}
}
..then you can have a common handler, eg:
void RX_TX_Handle(string key, string token)
{
token == receiveToken ? RX_Handle(key) : TX_Handle(key);
}
How about a different approach and use a regular expression. Mixin a little bit of LINQ and you have some pretty easy to follow code.
static void ParseLine(
string line,
int keyIndex,
int keyLength,
Action<List<byte>> txHandler,
Action<List<byte>> rxHandler)
{
var re = new Regex(#"\[(TX|RX)\](?: ([0-9a-f]{2}))+");
var match = re.Match(line);
if (match.Success)
{
var mode = match.Groups[1].Value; // either TX or RX
var values = match.Groups[2]
.Captures.Cast<Capture>()
.Skip(keyIndex)
.Take(keyLength)
.Select(c => Convert.ToByte(c.Value, 16))
.ToList();
if (mode == "TX") txHandler(values);
else if (mode == "RX") rxHandler(values);
}
}
Or without regular expressions:
static void ParseLine(
string line,
int keyIndex,
int keyLength,
Action<List<byte>> txHandler,
Action<List<byte>> rxHandler)
{
var start = line.IndexOf('[');
var end = line.IndexOf(']', start);
var mode = line.Substring(start + 1, end - start - 1);
var values = line.Substring(end + 1)
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Skip(keyIndex)
.Take(keyLength)
.Select(s => Convert.ToByte(s, 16))
.ToList();
if (mode == "TX") txHandler(values);
else if (mode == "RX") rxHandler(values);
}
I am not 100% sure if this answers your questions but I would create a TokenParser class that is responsible for parsing a token. You'll find it much easier to unit test.
public enum TokenType
{
Unknown = 0,
Tx = 1,
Rx = 2
}
public class Token
{
public TokenType TokenType { get; set; }
public IEnumerable<string> Values { get; set; }
}
public class TokenParser
{
public Token ParseToken(string input)
{
if (string.IsNullOrWhiteSpace(input)) throw new ArgumentNullException("input");
var token = new Token { TokenType = TokenType.Unknown };
input = input.ToUpperInvariant();
if (input.Contains("[TX]"))
{
token.TokenType = TokenType.Tx;
}
if (input.Contains("[RX]"))
{
token.TokenType = TokenType.Rx;
}
input = input.Substring(input.LastIndexOf("]", System.StringComparison.Ordinal) + 1);
token.Values = input.Trim().Split(Convert.ToChar(" "));
return token;
}
}
The example could be easily extended to allow multiple token parsers if the logic for parsing each token is vastly different.