How to get input separated by spaces - c#

I want to try and get a line of numbers and count them and store them in an array. I want to have the user input numbers up to 100 and I want the program to be able to separate them by spaces and count them in C#
Example: 98 92 86 92 100 92 93
The spaces will be the only separator and it would count 7 grades and store them in an array but I'm not sure how to to really do this.

Not to get empty entries in case of 2 spaces
var ints = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(i => int.Parse(i))
.ToList(); //or ToArray() whichever you want

Since you want an Array on this, use Split function.
string x = "98 92 86 92 100 92 93";
string[] val = x.Split(' ');
int totalCount = val.Length;
or a better way to do this is by using LINQ which automatically converts into array of integers
string x = "98 92 86 92 100 92 93";
int[] y = x.Split(' ').Select(n => Convert.ToInt32(n)).ToArray();
int totalCount = y.Length;

Related

parse hex incoming / create outgoing strings

I've modified an example to send & receive from serial, and that works fine.
The device I'm connecting to has three commands I need to work with.
My experience is with C.
MAP - returns a list of field_names, (decimal) values & (hex) addresses
I can keep track of which values are returned as decimal or hex.
Each line is terminated with CR
:: Example:
MEMBERS:10 - number of (decimal) member names
NAME_LENGTH:15 - (decimal) length of each name string
NAME_BASE:0A34 - 10 c-strings of (15) characters each starting at address (0x0A34) (may have junk following each null terminator)
etc.
GET hexaddr hexbytecount - returns a list of 2-char hex values starting from (hexaddr).
The returned bytes are a mix of bytes/ints/longs, and null terminated c-strings terminated with CR
:: Example::
get 0a34 10 -- will return
0A34< 54 65 73 74 20 4D 65 20 4F 75 74 00 40 D3 23 0B
This happens to be 'Test Me Out'(00) followed by junk
etc.
PUT hexaddr hexbytevalue {{value...} {value...}} sends multiple hex byte values separated by spaces starting at hex address, terminated by CR/LF
These bytes are a mix of bytes/ints/longs, and null terminated c-strings :: Example:
put 0a34 50 75 73 68 - (ascii Push)
Will replace the first 4-chars at 0x0A34 to become 'Push Me Out'
SAVED OK
See my answer previously about serial handling, which might be useful Serial Port Polling and Data handling
to convert your response to actual text :-
var s = "0A34 < 54 65 73 74 20 4D 65 20 4F 75 74 00 40 D3 23 0B";
var hex = s.Substring(s.IndexOf("<") + 1).Trim().Split(new char[] {' '});
var numbers = hex.Select(h => Convert.ToInt32(h, 16)).ToList();
var toText = String.Join("",numbers.TakeWhile(n => n!=0)
.Select(n => Char.ConvertFromUtf32(n)).ToArray());
Console.WriteLine(toText);
which :-
skips through the string till after the < character, then splits the rest into hex string
then, converts each hex string into ints ( base 16 )
then, takes each number till it finds a 0 and converts each number to text (using UTF32 encoding)
then, we join all the converted strings together to recreate the original text
alternatively, more condensed
var hex = s.Substring(s.IndexOf("<") + 1).Trim().Split(new char[] {' '});
var bytes = hex.Select(h => (byte) Convert.ToInt32(h, 16)).TakeWhile(n => n != 0);
var toText = Encoding.ASCII.GetString(bytes.ToArray());
for converting to hex from a number :-
Console.WriteLine(123.ToString("X"));
Console.WriteLine(123.ToString("X4"));
Console.WriteLine(123.ToString("X8"));
Console.WriteLine(123.ToString("x4"));
also you will find playing with hex data is well documented at https://msdn.microsoft.com/en-us/library/bb311038.aspx

How i can sort space delimiter string in a file?

I have a file delimited string by space
44 34 56 25
18 3 50 23
19 21 34 08
and output this
25 34 44 56
3 18 23 50
08 19 21 34
Code
string content = File.ReadAllText("finalregex2.txt");
string[] lines = Regex.Split(content, "( )+");
Array.Sort(lines);
I'm trying to sort but I don't know how complete this command
please help me to complete my command
cs0117 string doesn contain definition
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Linq;
class Program
{
static void Main()
{
var result = File.ReadAllLines("finalregex2.txt")
.Where(line => !string.IsNullOrWhiteSpace(line))
.Select(line => string.Join(" ", line.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.OrderBy(value => int.Parse(value))))
.ToList();
}
}
Instead of useing ReadAllText use ReadAllLines and then use .Split on each line:
var result = File.ReadAllLines("finalregex2.txt")
.Select(line => string.Join(" ", line.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.OrderBy(value => int.Parse(value)))).ToList();
If also in your real file you have empty lines between those with the numbers then add between the ReadAllLines and the Select:
.Where(line => !string.IsNullOrWhiteSpace(line))

what is the best way to split string in c#

I have a string that look like that "a,b,c,d,e,1,4,3,5,8,7,5,1,2,6.... and so on.
I am looking for the best way to split it and make it look like that:
a b c d e
1 4 3 5 8
7 5 1 2 6
Assuming, that you have a fix number of columns (5):
string Input = "a,b,c,d,e,11,45,34,33,79,65,75,12,2,6";
int i = 0;
string[][] Result = Input.Split(',').GroupBy(s => i++/5).Select(g => g.ToArray()).ToArray();
First I split the string by , character, then i group the result into chunks of 5 items and select those chunks into arrays.
Result:
a b c d e
11 45 34 33 79
65 75 12 2 6
to write that result into a file you have to
using (System.IO.StreamWriter writer =new System.IO.StreamWriter(path,false))
{
foreach (string[] line in Result)
{
writer.WriteLine(string.Join("\t", line));
}
};

Reading lines after specific string in a text file then storing data in lists

I have a program that reads texts files and I'm wanting it to collect data after a certain title in the text file, in this case [HRData]. Once the streamreader reaches [HRData] I want it to read every line after that and store each line in a list, but allowing me to get access to the seperate numbers.
The text file is like so:
[HRZones]
190
175
162
152
143
133
0
0
0
0
0
[SwapTimes]
[Trip]
250
0
3978
309
313
229
504
651
//n header
[HRData]
91 154 70 309 83 6451
91 154 70 309 83 6451
92 160 75 309 87 5687
94 173 80 309 87 5687
96 187 87 309 95 4662
100 190 93 309 123 4407
101 192 97 309 141 4915
103 191 98 309 145 5429
So referring to the text file, I want it to store the first line after [HRData] and allow me access each variable, for example 91 being [0].
I have code that already stores to a list if the word matches the regex, but I do not know how to code it to read after a specific string like [HRData].
if (squareBrackets.Match(line).Success) {
titles.Add(line);
if (textAfterTitles.Match(line).Success) {
textaftertitles.Add(line);
}
}
This is my attempt so far:
if (line.Contains("[HRData]")) {
inttimes = true;
MessageBox.Show("HRDATA Found");
if (inttimes == true) {
while (null != (line = streamReader.ReadLine())) {
//ADD LINE AND BREAK UP INTO PARTS S
}
}
}
You can call a LINQ-friendly method File.ReadLines , then you can use LINQ to get the part you want:
List<string> numbers = File.ReadLines("data.txt")
.SkipWhile(line => line != "[HRData]")
.Skip(1)
.SelectMany(line => line.Split())
.ToList();
Console.WriteLine(numbers[0]); // 91
Edit - this will give you all the numbers in one List<string>, if you want to keep the line order, use Select instead of SelectMany:
List<List<string>> listsOfNums = File.ReadLines("data.txt")
.SkipWhile(line => line != "[HRData]")
.Skip(1)
.Select(line => line.Split().ToList())
.ToList();
Note that this requires additional index to get a single number:
Console.WriteLine(listsOfNums[0][0]); // 91
You could use a variable to track the current section:
var list = new List<int[]>();
using (StreamReader streamReader = ...)
{
string line;
string sectionName = null;
while (null != (line = streamReader.ReadLine()))
{
var sectionMatch = Regex.Match(line, #"\s*\[\s*(?<NAME>[^\]]+)\s*\]\s*");
if (sectionMatch.Success)
{
sectionName = sectionMatch.Groups["NAME"].Value;
}
else if (sectionName == "HRData")
{
// You can process lines inside the `HRData` section here.
// Getting the numbers in the line, and adding to the list, one array for each line.
var nums = Regex.Matches(line, #"\d+")
.Cast<Match>()
.Select(m => m.Value)
.Select(int.Parse)
.ToArray();
list.Add(nums);
}
}
}
Presuming your current code attempt works, which I have not gone through to verify...
You could simply do the following:
List<int> elements = new List<int>();
while (null != (line = streamReader.ReadLine()))
{
if(line.Contains("["))
{
//Prevent reading in the next section
break;
}
string[] split = line.Split(Convert.ToChar(" "));
//Each element in split will be each number on each line.
for(int i=0;i<split.Length;i++)
{
elements.Add(Convert.ToInt32(split[i]));
}
}
Alternatively, if you want a 2 dimensional list, such that you can reference the numbers by line, you could use a nested list. For each run of the outer loop, create a new list and add it to elements (elements would be List<List<int>>).
Edit
Just a note, be careful with the Convert.ToInt32() function. It should really be in a try catch statement just in case some text is read in that isn't numeric.
Edit
Ok.. to make the routine more robust (per my comment below):
First make sure the routine doesn't go beyond your block of numbers. I'm not sure what is beyond the block you listed, so that will be up to you, but it should take the following form:
If(line.Contains("[") || line.Contains("]") || etc etc etc)
{
break;
}
Next thing is pre-format your split values. Inside the for statement:
for(int i=0;i<split.Length;i++)
{
string val = split[i].Trim(); //Get rid of white space
val = val.Replace("\r\n",""); //Use one of these to trim every character.
val = val.Replace("\n","");
try
{
elements.Add(Convert.ToInt32());
}
catch (Exception ex)
{
string err = ex.Message;
//You might try formatting the split value even more here and retry convert
}
}
To access the individual numbers (presuming you are using a single dimension list) there are a couple ways to do this. If you want to access by index value:
elements.ElementAt(index)
if you want to iterate through the list of values:
foreach(int val in elements)
{
}
If you need to know exactly what line the value came from, I suggest a 2d list. It would be implemented as follows (I'm copying my code from the original code snippet, so assume all of the error checking is added!)
List<List<int>> elements = new List<List<int>>();
while (null != (line = streamReader.ReadLine()))
{
if(line.Contains("["))
{
//Prevent reading in the next section
break;
}
List<int> newLine = new List<int>();
string[] split = line.Split(Convert.ToChar(" "));
//Each element in split will be each number on each line.
for(int i=0;i<split.Length;i++)
{
newLine.Add(Convert.ToInt32(split[i]));
}
elements.Add(newLine);
}
Now to access each element by line:
foreach(var line in elements)
{
//line is a List<int>
int value = line.ElementAt(index); //grab element at index for the given line.
}
Alternatively, if you need to reference directly by line index, and column index
int value = elements.ElementAt(lineIndex).ElementAt(columnIndex);
Be careful with all of these direct index references. You could pretty easily get an index out of bounds issue.
One other thing.. you should probably put a breakpoint on your Convert.ToInt statement and find what string it is breaking on. If you can assume that the data input will be consistent, then finding exactly what string is breaking the conversion will help you create a routine that handles the particular characters that are filtering in. I am going to guess that the method broke when it attempted to Convert the last split value to an integer, and we had not removed line endings.

orderby () containing numbers and letters

I want to order an array containing numbers and letters in an ascending order
the values are stored as a string in a DB.
This is the list I have
4B
1A
1
1B
2
4C
4
and want them to order like this where numbers are ascending followed by letters alphabetically.
1
1A
1B
2
4
4B
4C
So far I tried
allScenes.OrderBy(x => Convert.ToInt32(x.SceneNumber)).ToList()
and
allScenes.OrderBy(x => Convert.int.parse(x.SceneNumber)).ToList()
but both don't work because of the letters after the number.
Any idea how I can make this work?
Given your example data where the first number is always a single digit:
allScenes.OrderBy(x => x.SceneNumber).ToList()
If you can possibly have multi-digit numbers, please provide them and where you want them in the sort order.
This is one way to sort multiple digit numbers:
var allScenes = new[]{
new {SceneNumber="4B"},
new {SceneNumber="1A"},
new {SceneNumber="1"},
new {SceneNumber="1B"},
new {SceneNumber="2"},
new {SceneNumber="14"},
new {SceneNumber="4C"},
new {SceneNumber="14A"},
new {SceneNumber="200"},
new {SceneNumber="200A"},
new {SceneNumber="200B"}
};
var nums="0123456789".ToCharArray();
var result=allScenes
.OrderBy(x=>x.SceneNumber.LastIndexOfAny(nums))
.ThenBy(x=>x.SceneNumber);
Results:
1
1A
1B
2
4B
4C
14
14A
200
200A
200B
The database may not be able to convert the LastIndexOfAny function to something SQL-like, so you may need to do an .ToList() before the .OrderBy():
var nums="0123456789".ToCharArray();
var result=allScenes
.ToList()
.OrderBy(x=>x.SceneNumber.LastIndexOfAny(nums))
.ThenBy(x=>x.SceneNumber);
Very simple
string[] allScenes = {"4B","1A","1","1B","2","4C"};
var result = allScenes.OrderBy(x => x.First()).ThenBy(x => x.Last());
As values are stored as string into the database you just have to write OrderBy(e=> e).
The code below proves this works:
string[] items = {"4B", "1A", "1", "1B", "2", "4C", "4"};
items.OrderBy(e=> e)

Categories

Resources