How many elements ( values ) are in each line in a text file - c#

What to use in order to get the number of elements in each line. The example of the text file is given below. All I want to do is to get the number of elements in each line. Like the first line would have 4 elements, the second one 3 and so on.
1 5 4 6
2 4 6
1 9 8 7 5 3
3 2 1 1
private static void Skaitymaz(Trikampis[] trikampiai)
{
string line = null;
using (StreamReader reader = new StreamReader(#"U2.txt"))
{
string eilute = null;
while (null != (eilute = reader.ReadLine()))
{
int[] values = eilute.Split(' ');
}
}
}

Try,
string line = null;
using (StreamReader reader = new StreamReader(#"U2.txt"))
{
string eilute = null;
while (null != (eilute = reader.ReadLine()))
{
string[] values = eilute.Split(' ');
int noOfElement = values.Length;
}
}

You need to get length of the array after split,
values.Length

Something like that (Linq): read each line, split it by space or, probably, tabulation and count the items:
var numbers = File
.ReadLines(#"C:\MyText.txt")
.Select(line => line.Split(new Char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).Length);
// Test: 4, 3, 6, 4
Console.Write(String.Join(", ", numbers));

Related

How to sort an array of string representing numbers (positive and negative as well as having a decimal part)?

With Windows form application, I select a txt file with random numerical values and I can print it on the screen properly. But "Array.Sort (values)" didn't work when I wanted to sort the values. How can I handle this?
Button Click Function
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog
{
InitialDirectory = #"C:\",
Title = "Title",
CheckFileExists = true,
CheckPathExists = true,
DefaultExt = "txt",
Filter = "txt (*.txt)|*.txt",
FilterIndex = 2,
RestoreDirectory = true,
ReadOnlyChecked = true,
ShowReadOnly = true
};
if(openFileDialog1.ShowDialog()==DialogResult.OK)
{
string path = openFileDialog1.FileName;
string[] txtDoc = File.ReadAllLines(path);
textBox6.Text = path;
Array.Sort(txtDoc);
foreach (string s in txtDoc)
{
txtDoc = s.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
foreach (string ss in txtDoc)
{
richTextBox1.Text +=ss+"\n";
}
}
}
}
OUTPUT
10
2
5
-4
12,37
2
69
45
-4,41
35
76
35
-45
6
10
5
4
12
78
25
1
Sample txt
10 2 5 -4
6 10 5 4 12
35 -45
12,37
2 69 45 -4,41
35 76
78 25 1
You could sort the numbers with LINQ and parse them with double.TryParse(it seems you use comma as decimal separator):
string[] sortedNumbers = txtDoc
.SelectMany(line => line
.Split(' ', StringSplitOptions.RemoveEmptyEntries)
.Select(token => double.TryParse(token, out double value) ? value : (double?)null)
.Where(nullableDouble => nullableDouble.HasValue)
.Select(nullableDouble => nullableDouble.Value))
.OrderBy(value => value)
.Select(value => value.ToString())
.ToArray();
Array.Sort() is not working because you are trying to sort by string i.e trying to sort lines present in the text file instead of sorting all integers present in that file.
To solve your problem,
You need to read all lines from your file, This step is already done in your code.
Split each line by , then convert all strings into an array of double.
Then Sort it in ascending order.
Now update your richTextBox1
string[] txtDoc = File.ReadAllLines(path);
var sortedList = new List<double>();
foreach(var line in txtDoc)
{
var value = line.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
.Select(double.Parse)
.ToList()
sortedList.AddRange(value);
}
sortedList.Sort();
richTextBox1.Text = string.Join(Environment.NewLine, sortedList);
if txtDoc is an array that contains all your strings, you may order it this way:
string[] orderedList =
txtDoc.OrderBy(x => new string(x.Where(char.IsNumber).ToArray())).ToArray();

How to combine values of several lists into one in C#?

I'm trying to merge several values of diffrent lists into one line.
for example:
list A = [1,2,3,4,5,6,7,8,9]
list B = [A,B,C,D]
list C = [!,?,-]
then ill go with a loop through all lists and the output should be:
line = [1,A,!]
line = [2,B,?]
line = [3,C,-]
line = [4,D,NULL]
line = [5,NULL, NULL]
line = [6 ,NULL ,NULL]...
The result will be added into one object
So far I tried to iterate through my lists with foreach loops but after I debugging it's clear that my approach cant work:
foreach (var item in list1){
foreach (var item2 in list2){
foreach (var item3 in list3){
string line = makeStringFrom(item, item2, item3);
}
}
}
But I dont know how to make it work.
You can also use LINQ functions.
var listA = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var listB = new List<string> { "A", "B", "C", "D" };
var listC = new List<string> { "!", "?", "-" };
var result = Enumerable.Range(0, Math.Max(Math.Max(listA.Count, listB.Count), listC.Count))
.Select(i => new
{
a = listA.ElementAtOrDefault(i),
b = listB.ElementAtOrDefault(i),
c = listC.ElementAtOrDefault(i)
}).ToList();
foreach (var item in result)
{
Console.WriteLine("{0} {1} {2}", item.a, item.b, item.c);
}
Result:
1 A !
2 B ?
3 C -
4 D
5
6
7
8
9
The general method would be:
Find the maximum length of all of the lists
Then create a loop to go from 0 to the max length-1
Check if each list contains that index of the item, and if so,
retrieve the value, otherwise return null
Build your line from those values
You can use this:
var A = new List<string>() { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
var B = new List<string>() { "A", "B", "C", "D" };
var C = new List<string>() { "!", "?", "-"};
var lists = new List<List<string>>() { A, B, C };
int count = 0;
foreach ( var list in lists )
count = Math.Max(count, list.Count);
var result = new List<List<string>>();
for ( int index = 0; index < count; index++ )
{
var item = new List<string>();
result.Add(item);
foreach ( var list in lists )
item.Add(index < list.Count ? list[index] : null);
}
foreach ( var list in result )
{
string str = "";
foreach ( var item in list )
str += ( item == null ? "(null)" : item ) + " ";
str.TrimEnd(' ');
Console.WriteLine(str);
}
We create a list of the lists so you can use that for any number of lists.
Next we take the max count of these lists.
Then we parse them as indicated by the algorithm:
We create a new list.
We add this list to the result that is a list of lists.
We add in this new list each of others lists items while taking null is no more items available.
You can use a StringBuilder if you plan to manage several and big lists to optimize memory strings concatenation.
Fiddle Snippet
Output
1 A !
2 B ?
3 C -
4 D (null)
5 (null) (null)
6 (null) (null)
7 (null) (null)
8 (null) (null)
9 (null) (null)

How to exchange string content in a text file in C#?

I have a text file as follows:
1 ... 3 4 2
2 ... 3 21 4
3 ... 6 4 21 15
4 ... 14 21 12
I want to edit these strings, so that numbers after dotted parts to be splitted corresponding to the first number of each string. For example,
1
2 1
3 1 2
4 1 2 3
...
21 3 4
How can I do this?
Note: I obtain the first number group from a text file and edit it string by string. After that, I have written edited strings to the text file. In light of this, sample part of my code to obtain the first number group is provided as below:
for (var i = 0; i < existingLines.Length; i++)
{
var split = existingLines[i].Split('\t');
var act = i - 1;
var sc1 = int.Parse(split[6]);
var sc2 = int.Parse(split[7]);
appendedLines.Add(string.Format("{0} {1} {2}", act, sc1, sc2));
}
This LINQ code should get you started
string path = "c:\\temp\\test.txt";
using (var sr = new StreamReader(path))
{
var lines = new List<IEnumerable<int>>();
while (!sr.EndOfStream)
{
lines.Add(sr.ReadLine().Split(new[] { '.', ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)));
}
foreach (var node in lines.SelectMany(x => x).Distinct().OrderBy(x => x))
{
var predecessors = lines.Where(x => x.Skip(1).Contains(node))
.Select(x => x.First())
.OrderBy(x => x);
Console.WriteLine(node + " " + string.Join(" ", predecessors));
}
}
Output
2 1
3 1 2
4 1 2 3
6 3
12 4
14 4
15 3
21 2 3 4

Dividing a list of strings

Didn't quite know what to title this question so please feel free to edit.
I have a list of strings where all elements are strings with a length of 40.
What I want to do is split the list elements at character 20 and push the last part of the now divided string to the next element in the list, appending all other elements in the list.
E.g.
list[0] = 0011
list[1] = 2233
list[2] = 4455
^split here
// new list results in:
list[0] = 00
list[1] = 11
list[3] = 22
list[4] = 33
list[5] = 44
list[6] = 55
How can this be achieved?
list = list.SelectMany(s => new [] { s.Substring(0, 20), s.Substring(20, 20) })
.ToList();
list = list.SelectMany(x=>new[]{x.Substring(0, 20), x.Substring(20)}).ToList();
Not sure why you want to do that, but it's quite simple with linq:
List<string> split = list.SelectMany(s => new []{s.Substring(0, 2), s.Substring(2)}).ToList();
If you must work with the existing array:
const int elementCount = 3;
const int indexToSplit = 2;
string[] list = new string[elementCount * 2] { "0011", "0022", "0033", null, null, null };
for (int i = elementCount; i > 0; --i)
{
var str = list[i-1];
var left = str.Substring( 0, indexToSplit );
var right = str.Substring( indexToSplit, str.Length - indexToSplit );
var rightIndex = i * 2 - 1;
list[rightIndex] = right;
list[rightIndex - 1] = left;
}
foreach( var str in list )
{
Console.WriteLine( str );
}

How can I process this file in C#?

I have a text file with hundreds of entries formatted like this, I need to display this file on a data grid, or other user friendly control "properly formatted" as per your advise. (my intention is to then export it to excel not an optimal choice though for further processing. all the columns are values in milliseconds so most of times these values are quite big up to 3 hrs, so I need to convert them into hours/minutes/seconds.) What is the best way to approach this task? Can this be done with the StreamReader? Can the conversion take place in code so there is no need to export to excel? Any samples? thank you!
ENTRY DAY ENTRY TIME IN.WORK TEST % TRY CORRER CORTA CICLO MAQUI
O0.TXT
11/07/28 13:39:13 0 0 105 0 0 0 0
O0.TXT
11/07/20 00:00:00 0 0 19145 0 0 0 0
O0.TXT
11/07/19 15:04:10 0 0 32151 0 0 0 0
I want to format it as such:
FILE ENTRY DAY ENTRY TIME IN.WORK TEST % TRY CORRER CORTA CICLO MAQUI
O0.TXT 11/07/28 13:39:13 0 0 105 0 0 0 0
O0.TXT 11/07/20 00:00:00 0 0 19145 0 0 0 0
O0.TXT 11/07/19 15:04:10 0 0 32151 0 0 0 0
O0.TXT 11/07/07 05:22:40 0 0 508 0 0 0 0
I tried using the:
string fileName = "Myfile.txt";
StreamReader sr = new StreamReader(fileName);
string[] delimiter = new string[] { " " };
while (!sr.EndOfStream)
{
string[] lines = sr.ReadLine().Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
........
But I was not able to hold the format I wanted at all, nor to load it into a datagrid etc. for that matter.
string fileName = "Myfile.txt";
string[] delimiter = new string[] { " " };
List<string[]> rows = new List<string[]>();
string[] liens = File.ReadAllLines(fileName);
foreach (string line in liens)
{
rows.Add(line.Split(delimiter, StringSplitOptions.RemoveEmptyEntries));
}
//Now if you want to display them each one row item separated by tab "`\t"` or csv `","`
string separator = "\t";
List<string> output = new List<string>();
foreach (string[] row in rows)
{
output.Add(string.Join(separator, row));
}
string newFile = "result.txt";
File.WriteAllLines(newFile, output.ToArray());//save the output to new file.
Is everything fixed? For example, is the date always 6 characters in and 8 characters long (or whatever the case may be)? If so I would split on "\r\n" as opposed to " ", and then process each line individually. You could do:
string fileName = "Myfile.txt";
StreamReader sr = new StreamReader(fileName);
string[] delimiter = new string[] { "\r\n" };
while (!sr.EndOfStream)
{
string[] lines = sr.ReadLine().Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
date = line.Substring(6, 8);
// Do the other processing here.
}
}
Of course, you'll have to come up with some logic for which lines you need to process.

Categories

Resources